17 |
17 |
18 #-------------------------------------------------- |
18 #-------------------------------------------------- |
19 # SLAVE |
19 # SLAVE |
20 #-------------------------------------------------- |
20 #-------------------------------------------------- |
21 |
21 |
22 class _NodeEdit(objdictedit): |
|
23 " Overload some of CanFestival Node Editor methods " |
|
24 def OnCloseFrame(self, event): |
|
25 " Do reset _NodeListPlug.View when closed" |
|
26 self._onclose() |
|
27 event.Skip() |
|
28 |
|
29 class _SlavePlug(NodeManager): |
22 class _SlavePlug(NodeManager): |
30 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
23 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
31 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
24 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
32 <xsd:element name="CanFestivalNode"> |
25 <xsd:element name="CanFestivalSlaveNode"> |
33 <xsd:complexType> |
26 <xsd:complexType> |
34 <xsd:attribute name="CAN_Device" type="xsd:string" use="required"/> |
27 <xsd:attribute name="CAN_Device" type="xsd:string" use="required"/> |
35 <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="required"/> |
28 <xsd:attribute name="CAN_Baudrate" type="xsd:string" use="required"/> |
36 <xsd:attribute name="NodeId" type="xsd:string" use="required"/> |
29 <xsd:attribute name="NodeId" type="xsd:string" use="required"/> |
37 </xsd:complexType> |
30 </xsd:complexType> |
38 </xsd:element> |
31 </xsd:element> |
39 </xsd:schema> |
32 </xsd:schema> |
40 """ |
33 """ |
41 |
34 |
42 def GetSlaveODPath(self): |
35 def GetSlaveODPath(self): |
43 os.path.join(self.PlugPath(), 'slave.od') |
36 return os.path.join(self.PlugPath(), 'slave.od') |
44 |
37 |
45 def __init__(self): |
38 def __init__(self): |
46 # TODO change netname when name change |
39 # TODO change netname when name change |
47 NodeManager.__init__(self) |
40 NodeManager.__init__(self) |
48 odfilepath = self.GetSlaveODPath() |
41 odfilepath = self.GetSlaveODPath() |
63 if not self._View: |
56 if not self._View: |
64 def _onclose(): |
57 def _onclose(): |
65 self._View = None |
58 self._View = None |
66 def _onsave(): |
59 def _onsave(): |
67 self.GetPlugRoot().SaveProject() |
60 self.GetPlugRoot().SaveProject() |
68 self._View = _NodeEdit(self.GetPlugRoot().AppFrame, self) |
61 self._View = objdictedit(self.GetPlugRoot().AppFrame, self) |
69 # TODO redefine BusId when IEC channel change |
62 # TODO redefine BusId when IEC channel change |
70 self._View.SetBusId(self.GetCurrentLocation()) |
63 self._View.SetBusId(self.GetCurrentLocation()) |
71 self._View._onclose = _onclose |
64 self._View._onclose = _onclose |
72 self._View._onsave = _onsave |
65 self._View._onsave = _onsave |
73 self._View.Show() |
66 self._View.Show() |
74 |
67 |
75 def _ShowMasterGenerated(self, logger): |
|
76 buildpath = self._getBuildPath() |
|
77 # Eventually create build dir |
|
78 if not os.path.exists(buildpath): |
|
79 logger.write_error("Error: No PLC built\n") |
|
80 return |
|
81 |
|
82 masterpath = os.path.join(buildpath, "MasterGenerated.od") |
|
83 if not os.path.exists(masterpath): |
|
84 logger.write_error("Error: No Master generated\n") |
|
85 return |
|
86 |
|
87 new_dialog = objdictedit(None, [masterpath]) |
|
88 new_dialog.Show() |
|
89 |
|
90 PluginMethods = [ |
68 PluginMethods = [ |
91 {"bitmap" : os.path.join("images", "NetworkEdit"), |
69 {"bitmap" : os.path.join("images", "NetworkEdit"), |
92 "name" : "Edit network", |
70 "name" : "Edit slave", |
93 "tooltip" : "Edit CanOpen Network with NetworkEdit", |
71 "tooltip" : "Edit CanOpen slave with ObjdictEdit", |
94 "method" : "_OpenView"}, |
72 "method" : "_OpenView"}, |
95 {"name" : "Show Master", |
|
96 "tooltip" : "Show Master generated by config_utils", |
|
97 "method" : "_ShowMasterGenerated"} |
|
98 ] |
73 ] |
99 |
74 |
100 def OnPlugClose(self): |
75 def OnPlugClose(self): |
101 if self._View: |
76 if self._View: |
102 self._View.Close() |
77 self._View.Close() |
103 |
78 |
104 def PlugTestModified(self): |
79 def PlugTestModified(self): |
105 return self.ChangesToSave or self.HasChanged() |
80 return self.ChangesToSave or self.OneFileHasChanged() |
106 |
81 |
107 def OnPlugSave(self): |
82 def OnPlugSave(self): |
108 self.SetRoot(self.PlugPath()) |
83 return self.SaveCurrentInFile(self.GetSlaveODPath()) |
109 self.SaveProject() |
|
110 return True |
|
111 |
84 |
112 def PlugGenerate_C(self, buildpath, locations, logger): |
85 def PlugGenerate_C(self, buildpath, locations, logger): |
113 """ |
86 """ |
114 Generate C code |
87 Generate C code |
115 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
88 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
122 }, ...] |
95 }, ...] |
123 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
96 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
124 """ |
97 """ |
125 current_location = self.GetCurrentLocation() |
98 current_location = self.GetCurrentLocation() |
126 # define a unique name for the generated C file |
99 # define a unique name for the generated C file |
127 prefix = "_".join(map(lambda x:str(x), current_location)) |
100 prefix = "_".join(map(str, current_location)) |
128 Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix ) |
101 Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix ) |
129 # Create a new copy of the model with DCF loaded with PDO mappings for desired location |
102 # Create a new copy of the model |
130 master = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs(),"OD_%s"%prefix) |
103 slave = self.GetCurrentNodeCopy() |
131 res = gen_cfile.GenerateFile(Gen_OD_path, master) |
104 slave.SetNodeName("OD_%s"%prefix) |
|
105 # allow access to local OD from Slave PLC |
|
106 pointers = config_utils.LocalODPointers(locations, current_location, slave) |
|
107 res = gen_cfile.GenerateFile(Gen_OD_path, slave, pointers) |
132 if res : |
108 if res : |
133 raise Exception, res |
109 raise Exception, res |
134 |
110 self.ExportCurrentToEDSFile(os.path.join(buildpath, "Slave_%s.eds"%prefix)) |
135 file = open(os.path.join(buildpath, "MasterGenerated.od"), "w") |
|
136 dump(master, file) |
|
137 file.close() |
|
138 |
|
139 return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"",False |
111 return [(Gen_OD_path,canfestival_config.getCFLAGS(CanFestivalPath))],"",False |
140 |
112 |
141 #-------------------------------------------------- |
113 #-------------------------------------------------- |
142 # MASTER |
114 # MASTER |
143 #-------------------------------------------------- |
115 #-------------------------------------------------- |
144 |
|
145 class _NetworkEdit(networkedit): |
|
146 " Overload some of CanFestival Network Editor methods " |
|
147 def OnCloseFrame(self, event): |
|
148 " Do reset _NodeListPlug.View when closed" |
|
149 self._onclose() |
|
150 event.Skip() |
|
151 |
116 |
152 class _NodeListPlug(NodeList): |
117 class _NodeListPlug(NodeList): |
153 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
118 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
154 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
119 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
155 <xsd:element name="CanFestivalNode"> |
120 <xsd:element name="CanFestivalNode"> |
174 if not self._View: |
139 if not self._View: |
175 def _onclose(): |
140 def _onclose(): |
176 self._View = None |
141 self._View = None |
177 def _onsave(): |
142 def _onsave(): |
178 self.GetPlugRoot().SaveProject() |
143 self.GetPlugRoot().SaveProject() |
179 self._View = _NetworkEdit(self.GetPlugRoot().AppFrame, self) |
144 self._View = networkedit(self.GetPlugRoot().AppFrame, self) |
180 # TODO redefine BusId when IEC channel change |
145 # TODO redefine BusId when IEC channel change |
181 self._View.SetBusId(self.GetCurrentLocation()) |
146 self._View.SetBusId(self.GetCurrentLocation()) |
182 self._View._onclose = _onclose |
147 self._View._onclose = _onclose |
183 self._View._onsave = _onsave |
148 self._View._onsave = _onsave |
184 self._View.Show() |
149 self._View.Show() |
215 def PlugTestModified(self): |
180 def PlugTestModified(self): |
216 return self.ChangesToSave or self.HasChanged() |
181 return self.ChangesToSave or self.HasChanged() |
217 |
182 |
218 def OnPlugSave(self): |
183 def OnPlugSave(self): |
219 self.SetRoot(self.PlugPath()) |
184 self.SetRoot(self.PlugPath()) |
220 self.SaveProject() |
185 return self.SaveProject() is not None |
221 return True |
|
222 |
186 |
223 def PlugGenerate_C(self, buildpath, locations, logger): |
187 def PlugGenerate_C(self, buildpath, locations, logger): |
224 """ |
188 """ |
225 Generate C code |
189 Generate C code |
226 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
190 @param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5) |
233 }, ...] |
197 }, ...] |
234 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
198 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
235 """ |
199 """ |
236 current_location = self.GetCurrentLocation() |
200 current_location = self.GetCurrentLocation() |
237 # define a unique name for the generated C file |
201 # define a unique name for the generated C file |
238 prefix = "_".join(map(lambda x:str(x), current_location)) |
202 prefix = "_".join(map(str, current_location)) |
239 Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix ) |
203 Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix ) |
240 # Create a new copy of the model with DCF loaded with PDO mappings for desired location |
204 # Create a new copy of the model with DCF loaded with PDO mappings for desired location |
241 master, pointers = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs(),"OD_%s"%prefix) |
205 master, pointers = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs(),"OD_%s"%prefix) |
|
206 # allow access to local OD from Master PLC |
|
207 pointers.update(config_utils.LocalODPointers(locations, current_location, master)) |
|
208 # Do generate C file. |
242 res = gen_cfile.GenerateFile(Gen_OD_path, master, pointers) |
209 res = gen_cfile.GenerateFile(Gen_OD_path, master, pointers) |
243 if res : |
210 if res : |
244 raise Exception, res |
211 raise Exception, res |
245 |
212 |
246 file = open(os.path.join(buildpath, "MasterGenerated.od"), "w") |
213 file = open(os.path.join(buildpath, "MasterGenerated.od"), "w") |
286 "nodes_send_sync" : "", |
253 "nodes_send_sync" : "", |
287 "nodes_proceed_sync" : ""} |
254 "nodes_proceed_sync" : ""} |
288 for child in self.IECSortedChilds(): |
255 for child in self.IECSortedChilds(): |
289 childlocstr = "_".join(map(str,child.GetCurrentLocation())) |
256 childlocstr = "_".join(map(str,child.GetCurrentLocation())) |
290 nodename = "OD_%s" % childlocstr |
257 nodename = "OD_%s" % childlocstr |
|
258 |
|
259 # Try to get Slave Node |
|
260 child_data = getattr(child, "CanFestivalSlaveNode", None) |
|
261 if child_data is None: |
|
262 # Not a slave -> master |
|
263 child_data = getattr(child, "CanFestivalNode") |
|
264 if child_data.getSync_TPDOs(): |
|
265 format_dict["nodes_send_sync"] += 'NODE_SEND_SYNC(%s)\n '%(nodename) |
|
266 format_dict["nodes_proceed_sync"] += 'NODE_PROCEED_SYNC(%s)\n '%(nodename) |
291 |
267 |
292 format_dict["nodes_includes"] += '#include "%s.h"\n'%(nodename) |
268 format_dict["nodes_includes"] += '#include "%s.h"\n'%(nodename) |
293 format_dict["board_decls"] += 'BOARD_DECL(%s, "%s", "%s")\n'%( |
269 format_dict["board_decls"] += 'BOARD_DECL(%s, "%s", "%s")\n'%( |
294 nodename, |
270 nodename, |
295 child.CanFestivalNode.getCAN_Device(), |
271 child_data.getCAN_Device(), |
296 child.CanFestivalNode.getCAN_Baudrate()) |
272 child_data.getCAN_Baudrate()) |
297 format_dict["nodes_declare"] += 'NODE_DECLARE(%s, %s)\n '%( |
273 format_dict["nodes_declare"] += 'NODE_DECLARE(%s, %s)\n '%( |
298 nodename, |
274 nodename, |
299 child.CanFestivalNode.getNodeId()) |
275 child_data.getNodeId()) |
300 format_dict["nodes_init"] += 'NODE_INIT(%s, %s)\n '%( |
276 format_dict["nodes_init"] += 'NODE_INIT(%s, %s)\n '%( |
301 nodename, |
277 nodename, |
302 child.CanFestivalNode.getNodeId()) |
278 child_data.getNodeId()) |
303 format_dict["nodes_open"] += 'NODE_OPEN(%s)\n '%(nodename) |
279 format_dict["nodes_open"] += 'NODE_OPEN(%s)\n '%(nodename) |
304 format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n '%(nodename) |
280 format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n '%(nodename) |
305 format_dict["nodes_send_sync"] += 'NODE_SEND_SYNC(%s)\n '%(nodename) |
|
306 format_dict["nodes_proceed_sync"] += 'NODE_PROCEED_SYNC(%s)\n '%(nodename) |
|
307 |
281 |
308 if sys.platform == 'win32': |
282 if sys.platform == 'win32': |
309 if self.CanFestivalInstance.getDebug_mode() and os.path.isfile(os.path.join("%s"%(format_dict["candriver"] + '_DEBUG.dll'))): |
283 if self.CanFestivalInstance.getDebug_mode() and os.path.isfile(os.path.join("%s"%(format_dict["candriver"] + '_DEBUG.dll'))): |
310 format_dict["candriver"] += '_DEBUG.dll' |
284 format_dict["candriver"] += '_DEBUG.dll' |
311 else: |
285 else: |