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) |
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 |