changeset 129:9e350a7dde98

Changed architecture and updated the util
author Windel Bouwman
date Fri, 18 Jan 2013 12:52:11 +0100
parents 51cc127648e4
children 654093a9a1e3
files python/devices.py python/st-flash.py python/st-util.py python/stlink.py python/stm32.py
diffstat 5 files changed, 122 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/python/devices.py	Sun Jan 13 17:31:35 2013 +0100
+++ b/python/devices.py	Fri Jan 18 12:52:11 2013 +0100
@@ -1,13 +1,13 @@
 import sys
-
+import usb
 
 # Global device list to which devices are registered.
-deviceList = {}
+devices = {}
 
 def registerDevice(chipId):
    """ Decorator to register a device """
    def wrapper(dev):
-      deviceList[chipId] = dev
+      devices[chipId] = dev
       return dev
    return wrapper
 
@@ -20,21 +20,41 @@
       return iface
    return wrapper
 
+def createInterfaces():
+   """ Create a list of detected interfaces """
+   ctx = usb.UsbContext()
+
+   # Retrieve all usb devices:
+   devs = ctx.DeviceList
+   keys = interfaces.keys()
+
+   # Filter function to filter only registered interfaces:
+   def filt(usbiface):
+      return (usbiface.VendorId, usbiface.ProductId) in keys
+   def buildInterface(usbiface):
+      key = (usbiface.VendorId, usbiface.ProductId)
+      iface = interfaces[key]
+      return iface(usbiface)
+   return [buildInterface(uif) for uif in filter(filt, devs)]
+
 class Device:
    """
       Base class for a device possibly connected via an interface.
    """
-   pass
+   def __init__(self, iface):
+      # Store the interface through which this device is connected:
+      assert isinstance(iface, Interface)
+      self.iface = iface
 
 class Interface:
    """
       Generic interface class. Connected via Usb to a JTAG interface.
       Possibly is connected with a certain chip.
    """
-   def getDevice(self):
+   def createDevice(self):
       """ Try to get the device connected to this interface """
-      if self.ChipId in deviceList:
-         return deviceList[self.ChipId](self)
+      if self.ChipId in devices:
+         return devices[self.ChipId](self)
       raise STLinkException('No device found!')
 
 class STLinkException(Exception):
--- a/python/st-flash.py	Sun Jan 13 17:31:35 2013 +0100
+++ b/python/st-flash.py	Fri Jan 18 12:52:11 2013 +0100
@@ -51,7 +51,7 @@
    sys.exit(2)
 
 # Retrieve the connected device, if any:
-dev = stl.getDevice()
+dev = stl.createDevice()
 
 if args.command == 'read':
    dev_content = dev.readFlash(args.address, args.size)
--- a/python/st-util.py	Sun Jan 13 17:31:35 2013 +0100
+++ b/python/st-util.py	Fri Jan 18 12:52:11 2013 +0100
@@ -3,7 +3,8 @@
 import sys
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
-import stlink, usb
+import stlink, devices, stm32
+from devices import Interface, Device
 
 class InformationDialog(QDialog):
    def __init__(self, parent):
@@ -16,6 +17,69 @@
          fl.addRow('Current mode:', QLabel(parent.stl.CurrentModeString))
          fl.addRow('Status:', QLabel(parent.stl.StatusString))
 
+class DeviceTreeModel(QAbstractItemModel):
+   def __init__(self):
+      super().__init__()
+      self.chipPixmap = QPixmap('chip.png').scaled(32, 32)
+      self.usbPixmap = QPixmap('usb.png').scaled(32, 32)
+      self.refresh()
+   def refresh(self):
+      """ Check all usb interfaces for interfaces """
+      self.interfaces = devices.createInterfaces()
+      self.devices = []
+      self.modelReset.emit()
+   def addDevice(self, device):
+      if device.iface in [lambda d: d.iface for d in self.devices]:
+         print('device already open')
+         return
+      self.devices.append(device)
+      self.modelReset.emit()
+
+   def index(self, row, column, parent):
+      if parent.isValid():
+         ip = parent.internalPointer()
+         if isinstance(ip, Interface):
+            devs = [d for d in self.devices if d.iface is ip]
+            return self.createIndex(row, column, devs[row])
+      else:
+         # root level
+         iface = self.interfaces[row]
+         return self.createIndex(row, column, iface)
+      return idx
+   def parent(self, index):
+      if index.isValid():
+         ip = index.internalPointer()
+         if isinstance(ip, Interface):
+            return QModelIndex()
+         elif isinstance(ip, Device):
+            iface = ip.iface
+            row = self.interfaces.index(iface)
+            return self.createIndex(row, 0, iface)
+         return QModelIndex()
+   def rowCount(self, parent):
+      if parent.isValid():
+         # non-root level:
+         ip = parent.internalPointer()
+         if isinstance(ip, Interface):
+            devs = [d for d in self.devices if d.iface is ip]
+            return len(devs)
+      else:
+         # root level:
+         return len(self.interfaces)
+      return 0
+   def columnCount(self, parent):
+      return 1
+   def data(self, index, role):
+      if index.isValid():
+         ip = index.internalPointer()
+         if role == Qt.DisplayRole:
+            return str(ip)
+         elif role == Qt.DecorationRole:
+            if isinstance(ip, Interface):
+               return self.usbPixmap
+            if isinstance(ip, Device):
+               return self.chipPixmap
+
 class StUtil(QMainWindow):
    connected = pyqtSignal(bool)
    def __init__(self):
@@ -40,8 +104,23 @@
 
       sb = self.statusBar()
 
+      tv = QTreeView()
+      self.setCentralWidget(tv)
+      self.mdl = DeviceTreeModel()
+      tv.setModel(self.mdl)
+      tv.activated.connect(self.openItem)
+
       self.connected.connect(self.handleConnectedChange)
       self.connected.emit(False)
+   def openItem(self, idx):
+      if idx.isValid():
+         ip = idx.internalPointer()
+         if isinstance(ip, Interface):
+            ip.open()
+            # Try to get a device:
+            self.mdl.addDevice(ip.createDevice())
+         if isinstance(ip, Device):
+            self.device = ip
    def handleConnectedChange(self, state):
       self.miscMenu.setEnabled(state)
       self.connectAction.setEnabled(not state)
--- a/python/stlink.py	Sun Jan 13 17:31:35 2013 +0100
+++ b/python/stlink.py	Fri Jan 18 12:52:11 2013 +0100
@@ -1,5 +1,5 @@
 import struct, time
-from usb import UsbContext
+from usb import UsbContext, UsbDevice
 from devices import Interface, STLinkException, registerInterface
 
 ST_VID, STLINK2_PID = 0x0483, 0x3748
@@ -45,6 +45,7 @@
 class STLink2(Interface):
    """ STlink2 interface implementation. """
    def __init__(self, stlink2=None):
+      self.devHandle = None
       if not stlink2:
          context = UsbContext()
          stlink2s = list(filter(checkDevice, context.DeviceList))
@@ -53,9 +54,17 @@
          if len(stlink2s) > 1:
             print('More then one stlink2 found, picking first one')
          stlink2 = stlink2s[0]
+      assert isinstance(stlink2, UsbDevice) # Nifty type checking
       assert checkDevice(stlink2)
       self.stlink2 = stlink2
+   def __str__(self):
+      if self.devHandle:
+         return 'STlink2 device version {0}'.format(self.Version)
+      else:
+         return 'STlink2 device'
    def open(self):
+      if self.devHandle:
+         return
       self.devHandle = self.stlink2.open()
       if self.devHandle.Configuration != 1:
          self.devHandle.Configuration = 1
@@ -204,8 +213,6 @@
       if rxsize > 0:
          return self.devHandle.bulkRead(1, rxsize) # read from endpoint 1
 
-knownChipIds = {0x1: 'x'}
-
 if __name__ == '__main__':
    # Test program
    sl = STLink2()
@@ -218,10 +225,7 @@
    print('mode after entering swd mode:', sl.CurrentModeString)
 
    i = sl.ChipId
-   if i in knownChipIds:
-      print('chip id: 0x{0:X} -> {1}'.format(i, knownChipIds[i]))
-   else:
-      print('chip id: 0x{0:X}'.format(i))
+   print('chip id: 0x{0:X}'.format(i))
    print('cpu: {0}'.format(sl.CpuId))
 
    print('status: {0}'.format(sl.StatusString))
--- a/python/stm32.py	Sun Jan 13 17:31:35 2013 +0100
+++ b/python/stm32.py	Fri Jan 18 12:52:11 2013 +0100
@@ -55,9 +55,9 @@
 @registerDevice(0x10016413)
 class Stm32F4(Device):
    def __init__(self, iface):
-      super().__init__()
-      assert isinstance(iface, Interface)
-      self.iface = iface
+      super().__init__(iface)
+   def __str__(self):
+      return 'STM32F4 device'
    # flashing commands:
    def writeFlash(self, address, content):
       # TODO: