etherlab/etherlab.py
changeset 2062 c485269ec443
parent 2057 bb63c0479411
child 2063 c9a1c5bb51cd
equal deleted inserted replaced
2060:c7a2c9362d63 2062:c485269ec443
   157 if HAS_MCL:
   157 if HAS_MCL:
   158     
   158     
   159     NODE_VARIABLES = [
   159     NODE_VARIABLES = [
   160         ("ControlWord", 0x6040, 0x00, "UINT", "Q"),
   160         ("ControlWord", 0x6040, 0x00, "UINT", "Q"),
   161         ("TargetPosition", 0x607a, 0x00, "DINT", "Q"),
   161         ("TargetPosition", 0x607a, 0x00, "DINT", "Q"),
   162 #        ("ModesOfOperation", 0x06060, 0x00, "SINT", "Q"),
   162         ("ModesOfOperation", 0x06060, 0x00, "SINT", "Q"),
   163         ("StatusWord", 0x6041, 0x00, "UINT", "I"),
   163         ("StatusWord", 0x6041, 0x00, "UINT", "I"),
   164         ("ModesOfOperationDisplay", 0x06061, 0x00, "SINT", "I"),
   164         ("ModesOfOperationDisplay", 0x06061, 0x00, "SINT", "I"),
   165         ("ActualPosition", 0x6064, 0x00, "DINT", "I"),
   165         ("ActualPosition", 0x6064, 0x00, "DINT", "I"),
   166     ]
   166     ]
   167     
   167     
   177         """ % AxisXSD
   177         """ % AxisXSD
   178         
   178         
   179         NODE_PROFILE = 402
   179         NODE_PROFILE = 402
   180         EditorType = CIA402NodeEditor
   180         EditorType = CIA402NodeEditor
   181         
   181         
       
   182         ConfNodeMethods = [
       
   183             {"bitmap" : "CIA402AxisRef",
       
   184              "name" : _("Axis Ref"),
       
   185              "tooltip" : _("Initiate Drag'n drop of Axis ref located variable"),
       
   186              "method" : "_getCIA402AxisRef"},
       
   187         ]
       
   188         
   182         def GetIconPath(self):
   189         def GetIconPath(self):
   183             return os.path.join(CONFNODEFOLDER, "images", "CIA402Slave.png")
   190             return os.path.join(CONFNODEFOLDER, "images", "CIA402Slave.png")
       
   191         
       
   192         def GetDeviceLocationTree(self, slave_pos, current_location, device_name):
       
   193             axis_name = self.CTNName()
       
   194             vars = [{"name": "%s Axis Ref" % (axis_name),
       
   195                      "type": LOCATION_VAR_INPUT,
       
   196                      "size": "W",
       
   197                      "IEC_type": "AXIS_REF",
       
   198                      "var_name": axis_name,
       
   199                      "location": "%IW%s.0" % (".".join(map(str, current_location))),
       
   200                      "description": "",
       
   201                      "children": []}]
       
   202             vars.extend(_EthercatSlaveCTN.GetDeviceLocationTree(self, slave_pos, current_location, device_name))
       
   203             return vars
       
   204         
       
   205         def _getCIA402AxisRef(self):
       
   206             data = wx.TextDataObject(str(("%IW%s.0" % ".".join(map(str, self.GetCurrentLocation())), 
       
   207                                           "location", "AXIS_REF", self.CTNName(), "")))
       
   208             dragSource = wx.DropSource(self.GetCTRoot().AppFrame)
       
   209             dragSource.SetData(data)
       
   210             dragSource.DoDragDrop()
   184         
   211         
   185         def CTNGenerate_C(self, buildpath, locations):
   212         def CTNGenerate_C(self, buildpath, locations):
   186             """
   213             """
   187             Generate C code
   214             Generate C code
   188             @param current_location: Tupple containing confnode IEC location : %I0.0.4.5 => (0,0,4,5)
   215             @param current_location: Tupple containing confnode IEC location : %I0.0.4.5 => (0,0,4,5)
   305     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   332     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   306       <xsd:element name="EtherlabNode">
   333       <xsd:element name="EtherlabNode">
   307         <xsd:complexType>
   334         <xsd:complexType>
   308           <xsd:attribute name="MasterNumber" type="xsd:integer" use="optional" default="0"/>
   335           <xsd:attribute name="MasterNumber" type="xsd:integer" use="optional" default="0"/>
   309           <xsd:attribute name="ConfigurePDOs" type="xsd:boolean" use="optional" default="true"/>
   336           <xsd:attribute name="ConfigurePDOs" type="xsd:boolean" use="optional" default="true"/>
       
   337           <xsd:attribute name="DynamicPDOs" type="xsd:boolean" use="optional" default="true"/>
   310         </xsd:complexType>
   338         </xsd:complexType>
   311       </xsd:element>
   339       </xsd:element>
   312     </xsd:schema>
   340     </xsd:schema>
   313     """
   341     """
   314     
   342     
   495     def GetSlaveTypesLibrary(self, profile_filter=None):
   523     def GetSlaveTypesLibrary(self, profile_filter=None):
   496         return self.CTNParent.GetModulesLibrary(profile_filter)
   524         return self.CTNParent.GetModulesLibrary(profile_filter)
   497     
   525     
   498     def GetDeviceLocationTree(self, slave_pos, current_location, device_name):
   526     def GetDeviceLocationTree(self, slave_pos, current_location, device_name):
   499         slave = self.GetSlave(slave_pos)
   527         slave = self.GetSlave(slave_pos)
       
   528         vars = []    
   500         if slave is not None:
   529         if slave is not None:
   501             type_infos = slave.getType()
   530             type_infos = slave.getType()
   502         
   531         
   503             vars = []
       
   504             
       
   505             device = self.GetModuleInfos(type_infos)
   532             device = self.GetModuleInfos(type_infos)
   506             if device is not None:
   533             if device is not None:
   507                 sync_managers = []
   534                 sync_managers = []
   508                 for sync_manager in device.getSm():
   535                 for sync_manager in device.getSm():
   509                     sync_manager_control_byte = ExtractHexDecValue(sync_manager.getControlByte())
   536                     sync_manager_control_byte = ExtractHexDecValue(sync_manager.getControlByte())
   963                                      "type": pdo_type, 
   990                                      "type": pdo_type, 
   964                                      "entries": entries_infos,
   991                                      "entries": entries_infos,
   965                                      "entries_number": len(entries_infos),
   992                                      "entries_number": len(entries_infos),
   966                                      "fixed": pdo.getFixed() == True})
   993                                      "fixed": pdo.getFixed() == True})
   967                     
   994                     
   968                     dynamic_pdos = {}
   995                     if etherlab_node_infos.getDynamicPDOs():
   969                     dynamic_pdos_number = 0
   996                         dynamic_pdos = {}
   970                     for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), 
   997                         dynamic_pdos_number = 0
   971                                                            ("Outputs", 0x1a00, 0x1C00)]:
   998                         for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), 
   972                         for sync_manager in sync_managers:
   999                                                                ("Outputs", 0x1a00, 0x1C00)]:
   973                             if sync_manager["name"] == category:
  1000                             for sync_manager in sync_managers:
   974                                 category_infos = dynamic_pdos.setdefault(category, {})
  1001                                 if sync_manager["name"] == category:
   975                                 category_infos["sync_manager"] = sync_manager
  1002                                     category_infos = dynamic_pdos.setdefault(category, {})
   976                                 category_infos["pdos"] = [pdo for pdo in category_infos["sync_manager"]["pdos"] 
  1003                                     category_infos["sync_manager"] = sync_manager
   977                                                           if not pdo["fixed"] and pdo["type"] == category]
  1004                                     category_infos["pdos"] = [pdo for pdo in category_infos["sync_manager"]["pdos"] 
   978                                 category_infos["current_index"] = min_index
  1005                                                               if not pdo["fixed"] and pdo["type"] == category]
   979                                 category_infos["max_index"] = max_index
  1006                                     category_infos["current_index"] = min_index
   980                                 break
  1007                                     category_infos["max_index"] = max_index
   981                     
  1008                                     break
   982                     for (index, subindex), entry_declaration in slave_variables.iteritems():
       
   983                         
  1009                         
   984                         if not entry_declaration["mapped"]:
  1010                         for (index, subindex), entry_declaration in slave_variables.iteritems():
   985                             entry = device_entries.get((index, subindex), None)
       
   986                             if entry is None:
       
   987                                 raise ValueError, _("Unknown entry index 0x%4.4x, subindex 0x%2.2x for device %s") % \
       
   988                                                  (index, subindex, type_infos["device_type"])
       
   989                             
  1011                             
   990                             entry_infos = {
  1012                             if not entry_declaration["mapped"]:
   991                                 "index": index,
  1013                                 entry = device_entries.get((index, subindex), None)
   992                                 "subindex": subindex,
  1014                                 if entry is None:
   993                                 "name": entry["Name"],
  1015                                     raise ValueError, _("Unknown entry index 0x%4.4x, subindex 0x%2.2x for device %s") % \
   994                                 "bitlen": entry["BitSize"],
  1016                                                      (index, subindex, type_infos["device_type"])
   995                             }
  1017                                 
   996                             entry_infos.update(type_infos)
  1018                                 entry_infos = {
   997                             
  1019                                     "index": index,
   998                             entry_infos.update(dict(zip(["var_type", "dir", "var_name", "real_var"], entry_declaration["infos"])))
  1020                                     "subindex": subindex,
   999                             entry_declaration["mapped"] = True
  1021                                     "name": entry["Name"],
  1000                             
  1022                                     "bitlen": entry["BitSize"],
  1001                             if entry_infos["var_type"] != entry["Type"]:
  1023                                 }
  1002                                 message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
  1024                                 entry_infos.update(type_infos)
  1003                                 if (self.Controler.GetSizeOfType(entry_infos["var_type"]) != 
  1025                                 
  1004                                     self.Controler.GetSizeOfType(entry["Type"])):
  1026                                 entry_infos.update(dict(zip(["var_type", "dir", "var_name", "real_var"], entry_declaration["infos"])))
  1005                                     raise ValueError, message
  1027                                 entry_declaration["mapped"] = True
       
  1028                                 
       
  1029                                 if entry_infos["var_type"] != entry["Type"]:
       
  1030                                     message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
       
  1031                                     if (self.Controler.GetSizeOfType(entry_infos["var_type"]) != 
       
  1032                                         self.Controler.GetSizeOfType(entry["Type"])):
       
  1033                                         raise ValueError, message
       
  1034                                     else:
       
  1035                                         self.Controler.GetCTRoot().logger.write_warning(message + "\n")
       
  1036                                 
       
  1037                                 if entry_infos["dir"] == "I" and entry["PDOMapping"] in ["T", "RT"]:
       
  1038                                     pdo_type = "Inputs"
       
  1039                                 elif entry_infos["dir"] == "Q" and entry["PDOMapping"] in ["R", "RT"]:
       
  1040                                     pdo_type = "Outputs"
  1006                                 else:
  1041                                 else:
  1007                                     self.Controler.GetCTRoot().logger.write_warning(message + "\n")
  1042                                     raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
  1008                             
       
  1009                             if entry_infos["dir"] == "I" and entry["PDOMapping"] in ["T", "RT"]:
       
  1010                                 pdo_type = "Inputs"
       
  1011                             elif entry_infos["dir"] == "Q" and entry["PDOMapping"] in ["R", "RT"]:
       
  1012                                 pdo_type = "Outputs"
       
  1013                             else:
       
  1014                                 raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
       
  1015                             
       
  1016                             if not dynamic_pdos.has_key(pdo_type):
       
  1017                                 raise ValueError, _("No Sync manager defined for %s!") % pdo_type
       
  1018                             
       
  1019                             ConfigureVariable(entry_infos, str_completion)
       
  1020                             
       
  1021                             if len(dynamic_pdos[pdo_type]["pdos"]) > 0:
       
  1022                                 pdo = dynamic_pdos[pdo_type]["pdos"][0]
       
  1023                             else:
       
  1024                                 while dynamic_pdos[pdo_type]["current_index"] in pdos_index:
       
  1025                                     dynamic_pdos[pdo_type]["current_index"] += 1
       
  1026                                 if dynamic_pdos[pdo_type]["current_index"] >= dynamic_pdos[pdo_type]["max_index"]:
       
  1027                                     raise ValueError, _("No more free PDO index available for %s!") % pdo_type
       
  1028                                 pdos_index.append(dynamic_pdos[pdo_type]["current_index"])
       
  1029                                 
  1043                                 
  1030                                 dynamic_pdos_number += 1
  1044                                 if not dynamic_pdos.has_key(pdo_type):
  1031                                 pdo = {"slave": slave_idx,
  1045                                     raise ValueError, _("No Sync manager defined for %s!") % pdo_type
  1032                                        "index": dynamic_pdos[pdo_type]["current_index"],
  1046                                 
  1033                                        "name": "Dynamic PDO %d" % dynamic_pdos_number,
  1047                                 ConfigureVariable(entry_infos, str_completion)
  1034                                        "type": pdo_type, 
  1048                                 
  1035                                        "entries": [],
  1049                                 if len(dynamic_pdos[pdo_type]["pdos"]) > 0:
  1036                                        "entries_number": 0,
  1050                                     pdo = dynamic_pdos[pdo_type]["pdos"][0]
  1037                                        "fixed": False}
  1051                                 else:
  1038                                 dynamic_pdos[pdo_type]["sync_manager"]["pdos_number"] += 1
  1052                                     while dynamic_pdos[pdo_type]["current_index"] in pdos_index:
  1039                                 dynamic_pdos[pdo_type]["sync_manager"]["pdos"].append(pdo)
  1053                                         dynamic_pdos[pdo_type]["current_index"] += 1
  1040                                 dynamic_pdos[pdo_type]["pdos"].append(pdo)
  1054                                     if dynamic_pdos[pdo_type]["current_index"] >= dynamic_pdos[pdo_type]["max_index"]:
  1041                             
  1055                                         raise ValueError, _("No more free PDO index available for %s!") % pdo_type
  1042                             pdo["entries"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
  1056                                     pdos_index.append(dynamic_pdos[pdo_type]["current_index"])
  1043                             pdo["entries_number"] += 1
  1057                                     
  1044                             
  1058                                     dynamic_pdos_number += 1
  1045                             if pdo["entries_number"] == 255:
  1059                                     pdo = {"slave": slave_idx,
  1046                                 dynamic_pdos[pdo_type]["pdos"].pop(0)
  1060                                            "index": dynamic_pdos[pdo_type]["current_index"],
       
  1061                                            "name": "Dynamic PDO %d" % dynamic_pdos_number,
       
  1062                                            "type": pdo_type, 
       
  1063                                            "entries": [],
       
  1064                                            "entries_number": 0,
       
  1065                                            "fixed": False}
       
  1066                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos_number"] += 1
       
  1067                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos"].append(pdo)
       
  1068                                     dynamic_pdos[pdo_type]["pdos"].append(pdo)
       
  1069                                 
       
  1070                                 pdo["entries"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
       
  1071                                 pdo["entries_number"] += 1
       
  1072                                 
       
  1073                                 if pdo["entries_number"] == 255:
       
  1074                                     dynamic_pdos[pdo_type]["pdos"].pop(0)
  1047                             
  1075                             
  1048                     pdo_offset = 0
  1076                     pdo_offset = 0
  1049                     entry_offset = 0
  1077                     entry_offset = 0
  1050                     for sync_manager_infos in sync_managers:
  1078                     for sync_manager_infos in sync_managers:
  1051                         
  1079