Fix 'Transfer" button state according to last build result
authorlaurent
Thu, 02 Feb 2012 16:09:27 +0100
changeset 677 607731b33026
parent 676 04cd443cd18d
child 678 92a1ec3c6fdd
Fix 'Transfer" button state according to last build result
LPCBeremiz.py
plugger.py
targets/toolchain_gcc.py
targets/toolchain_makefile.py
--- a/LPCBeremiz.py	Thu Feb 02 00:28:27 2012 +0100
+++ b/LPCBeremiz.py	Thu Feb 02 16:09:27 2012 +0100
@@ -60,6 +60,8 @@
 
 from Beremiz import *
 from plugger import PluginsRoot, PlugTemplate, opjimg, connectors
+from plugins.canfestival import RootClass as CanOpenRootClass
+from plugins.canfestival.canfestival import _SlavePlug, _NodeListPlug, NodeManager
 from plcopen.structures import LOCATIONDATATYPES
 from PLCControler import LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP,\
                          LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
@@ -188,6 +190,9 @@
             return self.VariableLocationTree
         raise KeyError, "Only 'children' key is available"
     
+    def PlugEnabled(self):
+        return None
+    
     def SetIcon(self, icon):
         self.Icon = icon
     
@@ -355,6 +360,90 @@
         return [(Gen_Module_path, matiec_flags)],"",True
 
 #-------------------------------------------------------------------------------
+#                          LPC CanFestival Plugin Class
+#-------------------------------------------------------------------------------
+
+DEFAULT_SETTINGS = {
+    "CAN_Baudrate": "125K",
+    "Slave_NodeId": 2,
+    "Master_NodeId": 1,
+}
+
+class LPCCanOpenSlave(_SlavePlug):
+    XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
+    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+      <xsd:element name="CanFestivalSlaveNode">
+        <xsd:complexType>
+          <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="optional" default="%(CAN_Baudrate)s"/>
+          <xsd:attribute name="NodeId" type="xsd:string" use="optional" default="%(Slave_NodeId)d"/>
+          <xsd:attribute name="Sync_Align" type="xsd:integer" use="optional" default="0"/>
+          <xsd:attribute name="Sync_Align_Ratio" use="optional" default="50">
+            <xsd:simpleType>
+                <xsd:restriction base="xsd:integer">
+                    <xsd:minInclusive value="1"/>
+                    <xsd:maxInclusive value="99"/>
+                </xsd:restriction>
+            </xsd:simpleType>
+          </xsd:attribute>
+        </xsd:complexType>
+      </xsd:element>
+    </xsd:schema>
+    """ % DEFAULT_SETTINGS
+    
+    def __init__(self):
+        # TODO change netname when name change
+        NodeManager.__init__(self)
+        odfilepath = self.GetSlaveODPath()
+        if(os.path.isfile(odfilepath)):
+            self.OpenFileInCurrent(odfilepath)
+        else:
+            self.CreateNewNode("SlaveNode",  # Name - will be changed at build time
+                               0x00,         # NodeID - will be changed at build time
+                               "slave",      # Type
+                               "",           # description 
+                               "None",       # profile
+                               "", # prfile filepath
+                               "heartbeat",  # NMT
+                               [])           # options
+            self.OnPlugSave()
+    
+    def GetCanDevice(self):
+        return str(self.BaseParams.getIEC_Channel())
+    
+class LPCCanOpenMaster(_NodeListPlug):
+    XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
+    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+      <xsd:element name="CanFestivalNode">
+        <xsd:complexType>
+          <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="optional" default="%(CAN_Baudrate)s"/>
+          <xsd:attribute name="NodeId" type="xsd:string" use="optional" default="%(Master_NodeId)d"/>
+          <xsd:attribute name="Sync_TPDOs" type="xsd:boolean" use="optional" default="true"/>
+        </xsd:complexType>
+      </xsd:element>
+    </xsd:schema>
+    """ % DEFAULT_SETTINGS
+
+    def GetCanDevice(self):
+        return str(self.BaseParams.getIEC_Channel())
+
+class LPCCanOpen(CanOpenRootClass):
+    XSD = None
+    PlugChildsTypes = [("CanOpenNode",LPCCanOpenMaster, "CanOpen Master"),
+                       ("CanOpenSlave",LPCCanOpenSlave, "CanOpen Slave")]
+    
+    def LoadChilds(self):
+        PlugTemplate.LoadChilds(self)
+        
+        if self.GetChildByName("Master") is None:
+            master = self.PlugAddChild("Master", "CanOpenNode", 0)
+            master.BaseParams.setEnabled(False)
+        
+        if self.GetChildByName("Slave") is None:
+            slave = self.PlugAddChild("Slave", "CanOpenSlave", 1)
+            slave.BaseParams.setEnabled(False)
+    
+
+#-------------------------------------------------------------------------------
 #                              LPCPluginsRoot Class
 #-------------------------------------------------------------------------------
 
@@ -411,7 +500,7 @@
         
         PluginsRoot.__init__(self, frame, logger)
         
-        self.PlugChildsTypes += [("LPCBus", LPCBus, "LPC bus")]
+        self.PlugChildsTypes += [("LPCBus", LPCBus, "LPC bus"), ("CanOpen", LPCCanOpen, "CanOpen bus")]
         self.PlugType = "LPC"
         
         self.OnlineMode = "OFF"
@@ -590,6 +679,11 @@
             #Load and init all the childs
             self.LoadChilds()
         
+        if self.GetChildByName("CanOpen") is None:
+            canopen = self.PlugAddChild("CanOpen", "CanOpen", 0)
+            canopen.BaseParams.setEnabled(False)
+            canopen.LoadChilds()
+        
         if self.PlugTestModified():
             self.SaveProject()
         
@@ -800,6 +894,11 @@
             # warns controller that program match
             self.ProgramTransferred()
 
+    def ResetBuildMD5(self):
+        builder=self.GetBuilder()
+        if builder is not None:
+            builder.ResetBinaryCodeMD5()
+        
     def GetLastBuildMD5(self):
         builder=self.GetBuilder()
         if builder is not None:
@@ -811,20 +910,20 @@
         if self.CurrentMode is None and self.OnlineMode != "OFF":
             self.CurrentMode = TRANSFER_MODE
             
-            PluginsRoot._Build(self)
-            
-            ID_ABORTTRANSFERTIMER = wx.NewId()
-            self.AbortTransferTimer = wx.Timer(self.AppFrame, ID_ABORTTRANSFERTIMER)
-            self.AppFrame.Bind(wx.EVT_TIMER, self.AbortTransfer, self.AbortTransferTimer)  
-            
-            if self.OnlineMode == "BOOTLOADER":
-                self.BeginTransfer()
-            
-            else:
-                self.logger.write(_("Resetting PLC\n"))
-                #self.StatusTimer.Stop()
-                self.LPCConnector.ResetPLC()
-                self.AbortTransferTimer.Start(milliseconds=5000, oneShot=True)
+            if PluginsRoot._Build(self):
+            
+                ID_ABORTTRANSFERTIMER = wx.NewId()
+                self.AbortTransferTimer = wx.Timer(self.AppFrame, ID_ABORTTRANSFERTIMER)
+                self.AppFrame.Bind(wx.EVT_TIMER, self.AbortTransfer, self.AbortTransferTimer)  
+                
+                if self.OnlineMode == "BOOTLOADER":
+                    self.BeginTransfer()
+                
+                else:
+                    self.logger.write(_("Resetting PLC\n"))
+                    #self.StatusTimer.Stop()
+                    self.LPCConnector.ResetPLC()
+                    self.AbortTransferTimer.Start(milliseconds=5000, oneShot=True)
     
     def BeginTransfer(self):
         self.logger.write(_("Start PLC transfer\n"))
@@ -1038,9 +1137,14 @@
         
         self.PluginTreeSizer.AddWindow(leftwindow, 0, border=0, flag=wx.GROW)
         
+        leftwindowvsizer = wx.BoxSizer(wx.VERTICAL)
+        leftwindow.SetSizer(leftwindowvsizer)
+        
         leftwindowsizer = wx.BoxSizer(wx.HORIZONTAL)
-        leftwindow.SetSizer(leftwindowsizer)
-                
+        leftwindowvsizer.AddSizer(leftwindowsizer, 0, border=0, flag=0)
+        
+        self.GenerateEnableButton(leftwindow, leftwindowsizer, plugin)
+        
         st = wx.StaticText(leftwindow, -1)
         st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
         st.SetLabel(plugin.GetFullIEC_Channel())
@@ -1100,9 +1204,7 @@
         st.SetLabel(plugin.MandatoryParams[1].getName())
         leftwindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
         
-        rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
-        rightwindow.SetBackgroundColour(bkgdclr)
-        
+        rightwindow = self.GenerateParamsPanel(plugin, bkgdclr)
         self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW)
 
         self.PluginInfos[plugin]["left"] = leftwindow
--- a/plugger.py	Thu Feb 02 00:28:27 2012 +0100
+++ b/plugger.py	Thu Feb 02 16:09:27 2012 +0100
@@ -1260,6 +1260,12 @@
             self._builder = targetclass(self)
         return self._builder
 
+    def ResetBuildMD5(self):
+        builder=self.GetBuilder()
+        if builder is not None:
+            builder.ResetBinaryCodeMD5()
+        self.EnableMethod("_Transfer", False)
+
     def GetLastBuildMD5(self):
         builder=self.GetBuilder()
         if builder is not None:
@@ -1467,7 +1473,7 @@
         # If IEC code gen fail, bail out.
         if not IECGenRes:
             self.logger.write_error(_("IEC-61131-3 code generation failed !\n"))
-            self.EnableMethod("_Transfer", False)
+            self.ResetBuildMD5()
             return False
 
         # Reset variable and program list that are parsed from
@@ -1483,7 +1489,7 @@
         except Exception, exc:
             self.logger.write_error(_("Plugins code generation failed !\n"))
             self.logger.write_error(traceback.format_exc())
-            self.EnableMethod("_Transfer", False)
+            self.ResetBuildMD5()
             return False
 
         # Get temporary directory path
@@ -1519,7 +1525,7 @@
             except Exception, exc:
                 self.logger.write_error(name+_(" generation failed !\n"))
                 self.logger.write_error(traceback.format_exc())
-                self.EnableMethod("_Transfer", False)
+                self.ResetBuildMD5()
                 return False
 
         self.logger.write(_("C code generated successfully.\n"))
@@ -1528,7 +1534,7 @@
         builder = self.GetBuilder()
         if builder is None:
             self.logger.write_error(_("Fatal : cannot get builder.\n"))
-            self.EnableMethod("_Transfer", False)
+            self.ResetBuildMD5()
             return False
 
         # Build
@@ -1539,7 +1545,7 @@
         except Exception, exc:
             self.logger.write_error(_("C Build crashed !\n"))
             self.logger.write_error(traceback.format_exc())
-            self.EnableMethod("_Transfer", False)
+            self.ResetBuildMD5()
             return False
 
         self.logger.write(_("Successfully built.\n"))
--- a/targets/toolchain_gcc.py	Thu Feb 02 00:28:27 2012 +0100
+++ b/targets/toolchain_gcc.py	Thu Feb 02 16:09:27 2012 +0100
@@ -37,6 +37,13 @@
     def _GetMD5FileName(self):
         return os.path.join(self.buildpath, "lastbuildPLC.md5")
 
+    def ResetBinaryCodeMD5(self):
+        self.md5key = None
+        try:
+            os.remove(self._GetMD5FileName())
+        except Exception, e:
+            pass
+    
     def GetBinaryCodeMD5(self):
         if self.md5key is not None:
             return self.md5key
@@ -150,18 +157,18 @@
             
             if status :
                 return False
-            else :
-                # Calculate md5 key and get data for the new created PLC
-                data=self.GetBinaryCode()
-                self.md5key = hashlib.md5(data).hexdigest()
-    
-                # Store new PLC filename based on md5 key
-                f = open(self._GetMD5FileName(), "w")
-                f.write(self.md5key)
-                f.close()
+                
         else:
             self.PluginsRootInstance.logger.write("   [pass]  " + ' '.join(obns)+" -> " + self.exe + "\n")
-            
+        
+        # Calculate md5 key and get data for the new created PLC
+        data=self.GetBinaryCode()
+        self.md5key = hashlib.md5(data).hexdigest()
+
+        # Store new PLC filename based on md5 key
+        f = open(self._GetMD5FileName(), "w")
+        f.write(self.md5key)
+        f.close()
         
         return True
 
--- a/targets/toolchain_makefile.py	Thu Feb 02 00:28:27 2012 +0100
+++ b/targets/toolchain_makefile.py	Thu Feb 02 16:09:27 2012 +0100
@@ -24,6 +24,13 @@
     def _GetMD5FileName(self):
         return os.path.join(self.buildpath, "lastbuildPLC.md5")
 
+    def ResetBinaryCodeMD5(self):
+        self.md5key = None
+        try:
+            os.remove(self._GetMD5FileName())
+        except Exception, e:
+            pass
+
     def GetBinaryCodeMD5(self):
         if self.md5key is not None:
             return self.md5key