21 # |
21 # |
22 # You should have received a copy of the GNU General Public License |
22 # You should have received a copy of the GNU General Public License |
23 # along with this program; if not, write to the Free Software |
23 # along with this program; if not, write to the Free Software |
24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
25 |
25 |
26 import os, sys, shutil |
26 import os |
|
27 import sys |
|
28 import shutil |
|
29 import wx |
|
30 from gnosis.xml.pickle import * |
|
31 from gnosis.xml.pickle.util import setParanoia |
|
32 |
27 import util.paths as paths |
33 import util.paths as paths |
28 |
34 from util.TranslationCatalogs import AddCatalog |
29 base_folder = paths.AbsParentDir(__file__, 2) |
35 from ConfigTreeNode import ConfigTreeNode |
30 CanFestivalPath = os.path.join(base_folder, "CanFestival-3") |
36 from PLCControler import \ |
31 sys.path.append(os.path.join(CanFestivalPath, "objdictgen")) |
37 LOCATION_CONFNODE, \ |
32 |
38 LOCATION_MODULE, \ |
33 import wx |
39 LOCATION_GROUP, \ |
34 |
40 LOCATION_VAR_INPUT, \ |
35 from nodelist import NodeList |
41 LOCATION_VAR_OUTPUT, \ |
|
42 LOCATION_VAR_MEMORY |
|
43 |
|
44 try: |
|
45 from nodelist import NodeList |
|
46 except ImportError: |
|
47 base_folder = paths.AbsParentDir(__file__, 2) |
|
48 CanFestivalPath = os.path.join(base_folder, "CanFestival-3") |
|
49 sys.path.append(os.path.join(CanFestivalPath, "objdictgen")) |
|
50 |
|
51 from nodelist import NodeList |
|
52 |
|
53 |
36 from nodemanager import NodeManager |
54 from nodemanager import NodeManager |
37 import config_utils, gen_cfile, eds_utils |
55 import config_utils |
|
56 import gen_cfile |
|
57 import eds_utils |
38 import canfestival_config as local_canfestival_config |
58 import canfestival_config as local_canfestival_config |
39 from ConfigTreeNode import ConfigTreeNode |
59 |
40 from commondialogs import CreateNodeDialog |
60 from commondialogs import CreateNodeDialog |
41 from subindextable import IECTypeConversion, SizeConversion |
61 from subindextable import IECTypeConversion, SizeConversion |
42 |
|
43 from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY |
|
44 from SlaveEditor import SlaveEditor, MasterViewer |
62 from SlaveEditor import SlaveEditor, MasterViewer |
45 from NetworkEditor import NetworkEditor |
63 from NetworkEditor import NetworkEditor |
46 |
64 |
47 from gnosis.xml.pickle import * |
65 |
48 from gnosis.xml.pickle.util import setParanoia |
66 AddCatalog(os.path.join(CanFestivalPath, "objdictgen", "locale")) |
49 setParanoia(0) |
67 setParanoia(0) |
50 |
68 |
51 from util.TranslationCatalogs import AddCatalog |
69 |
52 AddCatalog(os.path.join(CanFestivalPath, "objdictgen", "locale")) |
70 # -------------------------------------------------- |
53 |
|
54 #-------------------------------------------------- |
|
55 # Location Tree Helper |
71 # Location Tree Helper |
56 #-------------------------------------------------- |
72 # -------------------------------------------------- |
|
73 |
57 |
74 |
58 def GetSlaveLocationTree(slave_node, current_location, name): |
75 def GetSlaveLocationTree(slave_node, current_location, name): |
59 entries = [] |
76 entries = [] |
60 for index, subindex, size, entry_name in slave_node.GetMapVariableList(): |
77 for index, subindex, size, entry_name in slave_node.GetMapVariableList(): |
61 subentry_infos = slave_node.GetSubentryInfos(index, subindex) |
78 subentry_infos = slave_node.GetSubentryInfos(index, subindex) |
154 def _OpenView(self, name=None, onlyopened=False): |
171 def _OpenView(self, name=None, onlyopened=False): |
155 ConfigTreeNode._OpenView(self, name, onlyopened) |
172 ConfigTreeNode._OpenView(self, name, onlyopened) |
156 if self._View is not None: |
173 if self._View is not None: |
157 self._View.SetBusId(self.GetCurrentLocation()) |
174 self._View.SetBusId(self.GetCurrentLocation()) |
158 return self._View |
175 return self._View |
159 |
176 |
160 def _ExportSlave(self): |
177 def _ExportSlave(self): |
161 dialog = wx.FileDialog(self.GetCTRoot().AppFrame, |
178 dialog = wx.FileDialog(self.GetCTRoot().AppFrame, |
162 _("Choose a file"), |
179 _("Choose a file"), |
163 os.path.expanduser("~"), |
180 os.path.expanduser("~"), |
164 "%s.eds" % self.CTNName(), |
181 "%s.eds" % self.CTNName(), |
165 _("EDS files (*.eds)|*.eds|All files|*.*"), |
182 _("EDS files (*.eds)|*.eds|All files|*.*"), |
166 wx.SAVE|wx.OVERWRITE_PROMPT) |
183 wx.SAVE | wx.OVERWRITE_PROMPT) |
167 if dialog.ShowModal() == wx.ID_OK: |
184 if dialog.ShowModal() == wx.ID_OK: |
168 result = eds_utils.GenerateEDSFile(dialog.GetPath(), self.GetCurrentNodeCopy()) |
185 result = eds_utils.GenerateEDSFile(dialog.GetPath(), self.GetCurrentNodeCopy()) |
169 if result: |
186 if result: |
170 self.GetCTRoot().logger.write_error(_("Error: Export slave failed\n")) |
187 self.GetCTRoot().logger.write_error(_("Error: Export slave failed\n")) |
171 dialog.Destroy() |
188 dialog.Destroy() |
172 |
189 |
173 ConfNodeMethods = [ |
190 ConfNodeMethods = [ |
174 {"bitmap" : "ExportSlave", |
191 { |
175 "name" : _("Export slave"), |
192 "bitmap": "ExportSlave", |
176 "tooltip" : _("Export CanOpen slave to EDS file"), |
193 "name": _("Export slave"), |
177 "method" : "_ExportSlave"}, |
194 "tooltip": _("Export CanOpen slave to EDS file"), |
|
195 "method": "_ExportSlave" |
|
196 }, |
178 ] |
197 ] |
179 |
198 |
180 def CTNTestModified(self): |
199 def CTNTestModified(self): |
181 return self.ChangesToSave or self.OneFileHasChanged() |
200 return self.ChangesToSave or self.OneFileHasChanged() |
182 |
201 |
183 def OnCTNSave(self, from_project_path=None): |
202 def OnCTNSave(self, from_project_path=None): |
184 return self.SaveCurrentInFile(self.GetSlaveODPath()) |
203 return self.SaveCurrentInFile(self.GetSlaveODPath()) |
185 |
204 |
186 def SetParamsAttribute(self, path, value): |
205 def SetParamsAttribute(self, path, value): |
187 result = ConfigTreeNode.SetParamsAttribute(self, path, value) |
206 result = ConfigTreeNode.SetParamsAttribute(self, path, value) |
188 |
207 |
189 # Filter IEC_Channel and Name, that have specific behavior |
208 # Filter IEC_Channel and Name, that have specific behavior |
190 if path == "BaseParams.IEC_Channel" and self._View is not None: |
209 if path == "BaseParams.IEC_Channel" and self._View is not None: |
191 self._View.SetBusId(self.GetCurrentLocation()) |
210 self._View.SetBusId(self.GetCurrentLocation()) |
192 |
211 |
193 return result |
212 return result |
194 |
213 |
195 def GetVariableLocationTree(self): |
214 def GetVariableLocationTree(self): |
196 current_location = self.GetCurrentLocation() |
215 current_location = self.GetCurrentLocation() |
197 return GetSlaveLocationTree(self.CurrentNode, |
216 return GetSlaveLocationTree(self.CurrentNode, |
198 self.GetCurrentLocation(), |
217 self.GetCurrentLocation(), |
199 self.BaseParams.getName()) |
218 self.BaseParams.getName()) |
200 |
219 |
201 def CTNGenerate_C(self, buildpath, locations): |
220 def CTNGenerate_C(self, buildpath, locations): |
202 """ |
221 """ |
203 Generate C code |
222 Generate C code |
204 @param current_location: Tupple containing confnode IEC location : %I0.0.4.5 => (0,0,4,5) |
223 @param current_location: Tupple containing confnode IEC location : %I0.0.4.5 => (0,0,4,5) |
205 @param locations: List of complete variables locations \ |
224 @param locations: List of complete variables locations \ |
212 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
231 @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND |
213 """ |
232 """ |
214 current_location = self.GetCurrentLocation() |
233 current_location = self.GetCurrentLocation() |
215 # define a unique name for the generated C file |
234 # define a unique name for the generated C file |
216 prefix = "_".join(map(str, current_location)) |
235 prefix = "_".join(map(str, current_location)) |
217 Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix ) |
236 Gen_OD_path = os.path.join(buildpath, "OD_%s.c" % prefix) |
218 # Create a new copy of the model |
237 # Create a new copy of the model |
219 slave = self.GetCurrentNodeCopy() |
238 slave = self.GetCurrentNodeCopy() |
220 slave.SetNodeName("OD_%s"%prefix) |
239 slave.SetNodeName("OD_%s" % prefix) |
221 # allow access to local OD from Slave PLC |
240 # allow access to local OD from Slave PLC |
222 pointers = config_utils.LocalODPointers(locations, current_location, slave) |
241 pointers = config_utils.LocalODPointers(locations, current_location, slave) |
223 res = gen_cfile.GenerateFile(Gen_OD_path, slave, pointers) |
242 res = gen_cfile.GenerateFile(Gen_OD_path, slave, pointers) |
224 if res : |
243 if res: |
225 raise Exception, res |
244 raise Exception(res) |
226 res = eds_utils.GenerateEDSFile(os.path.join(buildpath, "Slave_%s.eds"%prefix), slave) |
245 res = eds_utils.GenerateEDSFile(os.path.join(buildpath, "Slave_%s.eds" % prefix), slave) |
227 if res : |
246 if res: |
228 raise Exception, res |
247 raise Exception(res) |
229 return [(Gen_OD_path,local_canfestival_config.getCFLAGS(CanFestivalPath))],"",False |
248 return [(Gen_OD_path, local_canfestival_config.getCFLAGS(CanFestivalPath))], "", False |
230 |
249 |
231 def LoadPrevious(self): |
250 def LoadPrevious(self): |
232 self.LoadCurrentPrevious() |
251 self.LoadCurrentPrevious() |
233 |
252 |
234 def LoadNext(self): |
253 def LoadNext(self): |
235 self.LoadCurrentNext() |
254 self.LoadCurrentNext() |
236 |
255 |
237 def GetBufferState(self): |
256 def GetBufferState(self): |
238 return self.GetCurrentBufferState() |
257 return self.GetCurrentBufferState() |
239 |
258 |
240 #-------------------------------------------------- |
259 # -------------------------------------------------- |
241 # MASTER |
260 # MASTER |
242 #-------------------------------------------------- |
261 # -------------------------------------------------- |
|
262 |
243 |
263 |
244 class MiniNodeManager(NodeManager): |
264 class MiniNodeManager(NodeManager): |
245 |
265 |
246 def __init__(self, parent, filepath, fullname): |
266 def __init__(self, parent, filepath, fullname): |
247 NodeManager.__init__(self) |
267 NodeManager.__init__(self) |
248 |
268 |
249 self.OpenFileInCurrent(filepath) |
269 self.OpenFileInCurrent(filepath) |
250 |
270 |
251 self.Parent = parent |
271 self.Parent = parent |
252 self.Fullname = fullname |
272 self.Fullname = fullname |
253 |
273 |
254 def GetIconName(self): |
274 def GetIconName(self): |
255 return None |
275 return None |
256 |
276 |
257 def OnCloseEditor(self, view): |
277 def OnCloseEditor(self, view): |
258 self.Parent.OnCloseEditor(view) |
278 self.Parent.OnCloseEditor(view) |
259 |
279 |
260 def CTNFullName(self): |
280 def CTNFullName(self): |
261 return self.Fullname |
281 return self.Fullname |
262 |
282 |
263 def CTNTestModified(self): |
283 def CTNTestModified(self): |
264 return False |
284 return False |
265 |
285 |
266 def GetBufferState(self): |
286 def GetBufferState(self): |
267 return self.GetCurrentBufferState() |
287 return self.GetCurrentBufferState() |
268 |
288 |
269 ConfNodeMethods = [] |
289 ConfNodeMethods = [] |
|
290 |
270 |
291 |
271 class _NodeManager(NodeManager): |
292 class _NodeManager(NodeManager): |
272 |
293 |
273 def __init__(self, parent, *args, **kwargs): |
294 def __init__(self, parent, *args, **kwargs): |
274 NodeManager.__init__(self, *args, **kwargs) |
295 NodeManager.__init__(self, *args, **kwargs) |
275 self.Parent = parent |
296 self.Parent = parent |
276 |
297 |
277 def __del__(self): |
298 def __del__(self): |
278 self.Parent = None |
299 self.Parent = None |
279 |
300 |
280 def GetCurrentNodeName(self): |
301 def GetCurrentNodeName(self): |
281 return self.Parent.CTNName() |
302 return self.Parent.CTNName() |
282 |
303 |
283 def GetCurrentNodeID(self): |
304 def GetCurrentNodeID(self): |
284 return self.Parent.CanFestivalNode.getNodeId() |
305 return self.Parent.CanFestivalNode.getNodeId() |
285 |
306 |
|
307 |
286 class _NodeListCTN(NodeList): |
308 class _NodeListCTN(NodeList): |
287 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
309 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
288 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
310 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
289 <xsd:element name="CanFestivalNode"> |
311 <xsd:element name="CanFestivalNode"> |
290 <xsd:complexType> |
312 <xsd:complexType> |
293 <xsd:attribute name="NodeId" type="xsd:integer" use="optional" default="1"/> |
315 <xsd:attribute name="NodeId" type="xsd:integer" use="optional" default="1"/> |
294 <xsd:attribute name="Sync_TPDOs" type="xsd:boolean" use="optional" default="true"/> |
316 <xsd:attribute name="Sync_TPDOs" type="xsd:boolean" use="optional" default="true"/> |
295 </xsd:complexType> |
317 </xsd:complexType> |
296 </xsd:element> |
318 </xsd:element> |
297 </xsd:schema> |
319 </xsd:schema> |
298 """ |
320 """ |
299 |
321 |
300 EditorType = NetworkEditor |
322 EditorType = NetworkEditor |
301 IconPath = os.path.join(CanFestivalPath, "objdictgen", "networkedit.png") |
323 IconPath = os.path.join(CanFestivalPath, "objdictgen", "networkedit.png") |
302 |
324 |
303 def __init__(self): |
325 def __init__(self): |
304 manager = _NodeManager(self) |
326 manager = _NodeManager(self) |
305 NodeList.__init__(self, manager) |
327 NodeList.__init__(self, manager) |
306 self.LoadProject(self.CTNPath()) |
328 self.LoadProject(self.CTNPath()) |
307 self.SetNetworkName(self.BaseParams.getName()) |
329 self.SetNetworkName(self.BaseParams.getName()) |
308 |
330 |
309 def GetCanDevice(self): |
331 def GetCanDevice(self): |
310 return self.CanFestivalNode.getCAN_Device() |
332 return self.CanFestivalNode.getCAN_Device() |
311 |
333 |
312 def SetParamsAttribute(self, path, value): |
334 def SetParamsAttribute(self, path, value): |
313 if path == "CanFestivalNode.NodeId": |
335 if path == "CanFestivalNode.NodeId": |
314 nodeid = self.CanFestivalNode.getNodeId() |
336 nodeid = self.CanFestivalNode.getNodeId() |
315 if value != nodeid: |
337 if value != nodeid: |
316 slaves = self.GetSlaveIDs() |
338 slaves = self.GetSlaveIDs() |
317 dir = (value - nodeid) / abs(value - nodeid) |
339 dir = (value - nodeid) / abs(value - nodeid) |
318 while value in slaves and value >= 0: |
340 while value in slaves and value >= 0: |
319 value += dir |
341 value += dir |
320 if value < 0: |
342 if value < 0: |
321 value = nodeid |
343 value = nodeid |
322 |
344 |
323 value, refresh = ConfigTreeNode.SetParamsAttribute(self, path, value) |
345 value, refresh = ConfigTreeNode.SetParamsAttribute(self, path, value) |
324 refresh_network = False |
346 refresh_network = False |
325 |
347 |
326 # Filter IEC_Channel and Name, that have specific behavior |
348 # Filter IEC_Channel and Name, that have specific behavior |
327 if path == "BaseParams.IEC_Channel" and self._View is not None: |
349 if path == "BaseParams.IEC_Channel" and self._View is not None: |
328 self._View.SetBusId(self.GetCurrentLocation()) |
350 self._View.SetBusId(self.GetCurrentLocation()) |
329 elif path == "BaseParams.Name": |
351 elif path == "BaseParams.Name": |
330 self.SetNetworkName(value) |
352 self.SetNetworkName(value) |
331 refresh_network = True |
353 refresh_network = True |
332 elif path == "CanFestivalNode.NodeId": |
354 elif path == "CanFestivalNode.NodeId": |
333 refresh_network = True |
355 refresh_network = True |
334 |
356 |
335 if refresh_network and self._View is not None: |
357 if refresh_network and self._View is not None: |
336 wx.CallAfter(self._View.RefreshBufferState) |
358 wx.CallAfter(self._View.RefreshBufferState) |
337 return value, refresh |
359 return value, refresh |
338 |
360 |
339 def GetVariableLocationTree(self): |
361 def GetVariableLocationTree(self): |
340 current_location = self.GetCurrentLocation() |
362 current_location = self.GetCurrentLocation() |
341 nodeindexes = self.SlaveNodes.keys() |
363 nodeindexes = self.SlaveNodes.keys() |
342 nodeindexes.sort() |
364 nodeindexes.sort() |
343 return {"name": self.BaseParams.getName(), |
365 children = [] |
344 "type": LOCATION_CONFNODE, |
366 children += [GetSlaveLocationTree(self.Manager.GetCurrentNodeCopy(), |
345 "location": self.GetFullIEC_Channel(), |
367 current_location, |
346 "children": [GetSlaveLocationTree(self.Manager.GetCurrentNodeCopy(), |
368 _("Local entries"))] |
347 current_location, |
369 children += [GetSlaveLocationTree(self.SlaveNodes[nodeid]["Node"], |
348 _("Local entries"))] + |
370 current_location + (nodeid,), |
349 [GetSlaveLocationTree(self.SlaveNodes[nodeid]["Node"], |
371 self.SlaveNodes[nodeid]["Name"]) for nodeid in nodeindexes] |
350 current_location + (nodeid,), |
372 |
351 self.SlaveNodes[nodeid]["Name"]) |
373 return { |
352 for nodeid in nodeindexes] |
374 "name": self.BaseParams.getName(), |
|
375 "type": LOCATION_CONFNODE, |
|
376 "location": self.GetFullIEC_Channel(), |
|
377 "children": children |
353 } |
378 } |
354 |
379 |
355 _GeneratedMasterView = None |
380 _GeneratedMasterView = None |
|
381 |
356 def _ShowGeneratedMaster(self): |
382 def _ShowGeneratedMaster(self): |
357 self._OpenView("Generated master") |
383 self._OpenView("Generated master") |
358 |
384 |
359 def _OpenView(self, name=None, onlyopened=False): |
385 def _OpenView(self, name=None, onlyopened=False): |
360 if name == "Generated master": |
386 if name == "Generated master": |
361 app_frame = self.GetCTRoot().AppFrame |
387 app_frame = self.GetCTRoot().AppFrame |
362 if self._GeneratedMasterView is None: |
388 if self._GeneratedMasterView is None: |
363 buildpath = self._getBuildPath() |
389 buildpath = self._getBuildPath() |
364 # Eventually create build dir |
390 # Eventually create build dir |
365 if not os.path.exists(buildpath): |
391 if not os.path.exists(buildpath): |
366 self.GetCTRoot().logger.write_error(_("Error: No PLC built\n")) |
392 self.GetCTRoot().logger.write_error(_("Error: No PLC built\n")) |
367 return |
393 return |
368 |
394 |
369 masterpath = os.path.join(buildpath, "MasterGenerated.od") |
395 masterpath = os.path.join(buildpath, "MasterGenerated.od") |
370 if not os.path.exists(masterpath): |
396 if not os.path.exists(masterpath): |
371 self.GetCTRoot().logger.write_error(_("Error: No Master generated\n")) |
397 self.GetCTRoot().logger.write_error(_("Error: No Master generated\n")) |
372 return |
398 return |
373 |
399 |
374 manager = MiniNodeManager(self, masterpath, self.CTNFullName()) |
400 manager = MiniNodeManager(self, masterpath, self.CTNFullName()) |
375 self._GeneratedMasterView = MasterViewer(app_frame.TabsOpened, manager, app_frame, name) |
401 self._GeneratedMasterView = MasterViewer(app_frame.TabsOpened, manager, app_frame, name) |
376 |
402 |
377 if self._GeneratedMasterView is not None: |
403 if self._GeneratedMasterView is not None: |
378 app_frame.EditProjectElement(self._GeneratedMasterView, self._GeneratedMasterView.GetInstancePath()) |
404 app_frame.EditProjectElement(self._GeneratedMasterView, self._GeneratedMasterView.GetInstancePath()) |
379 |
405 |
380 return self._GeneratedMasterView |
406 return self._GeneratedMasterView |
381 else: |
407 else: |
382 ConfigTreeNode._OpenView(self, name, onlyopened) |
408 ConfigTreeNode._OpenView(self, name, onlyopened) |
383 if self._View is not None: |
409 if self._View is not None: |
384 self._View.SetBusId(self.GetCurrentLocation()) |
410 self._View.SetBusId(self.GetCurrentLocation()) |
385 return self._View |
411 return self._View |
386 |
412 |
387 ConfNodeMethods = [ |
413 ConfNodeMethods = [ |
388 {"bitmap" : "ShowMaster", |
414 { |
389 "name" : _("Show Master"), |
415 "bitmap": "ShowMaster", |
390 "tooltip" : _("Show Master generated by config_utils"), |
416 "name": _("Show Master"), |
391 "method" : "_ShowGeneratedMaster"} |
417 "tooltip": _("Show Master generated by config_utils"), |
|
418 "method": "_ShowGeneratedMaster" |
|
419 } |
392 ] |
420 ] |
393 |
421 |
394 def OnCloseEditor(self, view): |
422 def OnCloseEditor(self, view): |
395 ConfigTreeNode.OnCloseEditor(self, view) |
423 ConfigTreeNode.OnCloseEditor(self, view) |
396 if self._GeneratedMasterView == view: |
424 if self._GeneratedMasterView == view: |
397 self._GeneratedMasterView = None |
425 self._GeneratedMasterView = None |
398 |
426 |
399 def OnCTNClose(self): |
427 def OnCTNClose(self): |
400 ConfigTreeNode.OnCTNClose(self) |
428 ConfigTreeNode.OnCTNClose(self) |
401 self._CloseView(self._GeneratedMasterView) |
429 self._CloseView(self._GeneratedMasterView) |
402 return True |
430 return True |
403 |
431 |
404 def CTNTestModified(self): |
432 def CTNTestModified(self): |
405 return self.ChangesToSave or self.HasChanged() |
433 return self.ChangesToSave or self.HasChanged() |
406 |
434 |
407 def OnCTNSave(self, from_project_path=None): |
435 def OnCTNSave(self, from_project_path=None): |
408 self.SetRoot(self.CTNPath()) |
436 self.SetRoot(self.CTNPath()) |
409 if from_project_path is not None: |
437 if from_project_path is not None: |
410 shutil.copytree(self.GetEDSFolder(from_project_path), |
438 shutil.copytree(self.GetEDSFolder(from_project_path), |
411 self.GetEDSFolder()) |
439 self.GetEDSFolder()) |
412 return self.SaveProject() is None |
440 return self.SaveProject() is None |
413 |
441 |
414 def CTNGenerate_C(self, buildpath, locations): |
442 def CTNGenerate_C(self, buildpath, locations): |
415 """ |
443 """ |
426 """ |
454 """ |
427 self._CloseView(self._GeneratedMasterView) |
455 self._CloseView(self._GeneratedMasterView) |
428 current_location = self.GetCurrentLocation() |
456 current_location = self.GetCurrentLocation() |
429 # define a unique name for the generated C file |
457 # define a unique name for the generated C file |
430 prefix = "_".join(map(str, current_location)) |
458 prefix = "_".join(map(str, current_location)) |
431 Gen_OD_path = os.path.join(buildpath, "OD_%s.c"%prefix ) |
459 Gen_OD_path = os.path.join(buildpath, "OD_%s.c" % prefix) |
432 # Create a new copy of the model with DCF loaded with PDO mappings for desired location |
460 # Create a new copy of the model with DCF loaded with PDO mappings for desired location |
433 try: |
461 try: |
434 master, pointers = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs(),"OD_%s"%prefix) |
462 master, pointers = config_utils.GenerateConciseDCF(locations, current_location, self, self.CanFestivalNode.getSync_TPDOs(), "OD_%s" % prefix) |
435 except config_utils.PDOmappingException, e: |
463 except config_utils.PDOmappingException, e: |
436 raise Exception, e.message |
464 raise Exception(e.message) |
437 # Do generate C file. |
465 # Do generate C file. |
438 res = gen_cfile.GenerateFile(Gen_OD_path, master, pointers) |
466 res = gen_cfile.GenerateFile(Gen_OD_path, master, pointers) |
439 if res : |
467 if res: |
440 raise Exception, res |
468 raise Exception(res) |
441 |
469 |
442 file = open(os.path.join(buildpath, "MasterGenerated.od"), "w") |
470 file = open(os.path.join(buildpath, "MasterGenerated.od"), "w") |
443 dump(master, file) |
471 dump(master, file) |
444 file.close() |
472 file.close() |
445 |
473 |
446 return [(Gen_OD_path,local_canfestival_config.getCFLAGS(CanFestivalPath))],"",False |
474 return [(Gen_OD_path, local_canfestival_config.getCFLAGS(CanFestivalPath))], "", False |
447 |
475 |
448 def LoadPrevious(self): |
476 def LoadPrevious(self): |
449 self.Manager.LoadCurrentPrevious() |
477 self.Manager.LoadCurrentPrevious() |
450 |
478 |
451 def LoadNext(self): |
479 def LoadNext(self): |
452 self.Manager.LoadCurrentNext() |
480 self.Manager.LoadCurrentNext() |
453 |
481 |
454 def GetBufferState(self): |
482 def GetBufferState(self): |
455 return self.Manager.GetCurrentBufferState() |
483 return self.Manager.GetCurrentBufferState() |
456 |
484 |
|
485 |
457 class RootClass: |
486 class RootClass: |
458 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
487 XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?> |
459 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
488 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
460 <xsd:element name="CanFestivalInstance"> |
489 <xsd:element name="CanFestivalInstance"> |
461 <xsd:complexType> |
490 <xsd:complexType> |
462 <xsd:attribute name="CAN_Driver" type="xsd:string" use="optional"/> |
491 <xsd:attribute name="CAN_Driver" type="xsd:string" use="optional"/> |
463 </xsd:complexType> |
492 </xsd:complexType> |
464 </xsd:element> |
493 </xsd:element> |
465 </xsd:schema> |
494 </xsd:schema> |
466 """ |
495 """ |
467 |
496 |
468 CTNChildrenTypes = [("CanOpenNode",_NodeListCTN, "CanOpen Master"), |
497 CTNChildrenTypes = [("CanOpenNode", _NodeListCTN, "CanOpen Master"), |
469 ("CanOpenSlave",_SlaveCTN, "CanOpen Slave")] |
498 ("CanOpenSlave", _SlaveCTN, "CanOpen Slave")] |
470 def GetParamsAttributes(self, path = None): |
499 |
471 infos = ConfigTreeNode.GetParamsAttributes(self, path = path) |
500 def GetParamsAttributes(self, path=None): |
|
501 infos = ConfigTreeNode.GetParamsAttributes(self, path=path) |
472 for element in infos: |
502 for element in infos: |
473 if element["name"] == "CanFestivalInstance": |
503 if element["name"] == "CanFestivalInstance": |
474 for child in element["children"]: |
504 for child in element["children"]: |
475 if child["name"] == "CAN_Driver": |
505 if child["name"] == "CAN_Driver": |
476 child["type"] = local_canfestival_config.DLL_LIST |
506 child["type"] = local_canfestival_config.DLL_LIST |
477 return infos |
507 return infos |
478 |
508 |
479 def GetCanDriver(self): |
509 def GetCanDriver(self): |
480 res = self.CanFestivalInstance.getCAN_Driver() |
510 res = self.CanFestivalInstance.getCAN_Driver() |
481 if not res : |
511 if not res: |
482 return "" |
512 return "" |
483 return res |
513 return res |
484 |
514 |
485 def CTNGenerate_C(self, buildpath, locations): |
515 def CTNGenerate_C(self, buildpath, locations): |
486 can_driver = self.GetCanDriver() |
516 can_driver = self.GetCanDriver() |
487 if can_driver is not None: |
517 if can_driver is not None: |
488 can_drivers = local_canfestival_config.DLL_LIST |
518 can_drivers = local_canfestival_config.DLL_LIST |
489 if can_driver not in can_drivers : |
519 if can_driver not in can_drivers: |
490 can_driver = can_drivers[0] |
520 can_driver = can_drivers[0] |
491 can_drv_ext = self.GetCTRoot().GetBuilder().extension |
521 can_drv_ext = self.GetCTRoot().GetBuilder().extension |
492 can_drv_prefix = self.GetCTRoot().GetBuilder().dlopen_prefix |
522 can_drv_prefix = self.GetCTRoot().GetBuilder().dlopen_prefix |
493 can_driver_name = can_drv_prefix + "libcanfestival_" + can_driver + can_drv_ext |
523 can_driver_name = can_drv_prefix + "libcanfestival_" + can_driver + can_drv_ext |
494 else: |
524 else: |
495 can_driver_name = "" |
525 can_driver_name = "" |
496 |
526 |
497 |
527 format_dict = {"locstr": "_".join(map(str, self.GetCurrentLocation())), |
498 format_dict = {"locstr" : "_".join(map(str,self.GetCurrentLocation())), |
528 "candriver": can_driver_name, |
499 "candriver" : can_driver_name, |
529 "nodes_includes": "", |
500 "nodes_includes" : "", |
530 "board_decls": "", |
501 "board_decls" : "", |
531 "nodes_init": "", |
502 "nodes_init" : "", |
532 "nodes_open": "", |
503 "nodes_open" : "", |
533 "nodes_stop": "", |
504 "nodes_stop" : "", |
534 "nodes_close": "", |
505 "nodes_close" : "", |
535 "nodes_send_sync": "", |
506 "nodes_send_sync" : "", |
536 "nodes_proceed_sync": "", |
507 "nodes_proceed_sync" : "", |
537 "slavebootups": "", |
508 "slavebootups" : "", |
538 "slavebootup_register": "", |
509 "slavebootup_register" : "", |
539 "post_sync": "", |
510 "post_sync" : "", |
540 "post_sync_register": "", |
511 "post_sync_register" : "", |
541 "pre_op": "", |
512 "pre_op" : "", |
542 "pre_op_register": "", |
513 "pre_op_register" : "", |
|
514 } |
543 } |
515 for child in self.IECSortedChildren(): |
544 for child in self.IECSortedChildren(): |
516 childlocstr = "_".join(map(str,child.GetCurrentLocation())) |
545 childlocstr = "_".join(map(str, child.GetCurrentLocation())) |
517 nodename = "OD_%s" % childlocstr |
546 nodename = "OD_%s" % childlocstr |
518 |
547 |
519 # Try to get Slave Node |
548 # Try to get Slave Node |
520 child_data = getattr(child, "CanFestivalSlaveNode", None) |
549 child_data = getattr(child, "CanFestivalSlaveNode", None) |
521 if child_data is None: |
550 if child_data is None: |
522 # Not a slave -> master |
551 # Not a slave -> master |
523 child_data = getattr(child, "CanFestivalNode") |
552 child_data = getattr(child, "CanFestivalNode") |
524 # Apply sync setting |
553 # Apply sync setting |
525 format_dict["nodes_init"] += 'NODE_MASTER_INIT(%s, %s)\n '%( |
554 format_dict["nodes_init"] += 'NODE_MASTER_INIT(%s, %s)\n ' % ( |
526 nodename, |
555 nodename, |
527 child_data.getNodeId()) |
556 child_data.getNodeId()) |
528 if child_data.getSync_TPDOs(): |
557 if child_data.getSync_TPDOs(): |
529 format_dict["nodes_send_sync"] += 'NODE_SEND_SYNC(%s)\n '%(nodename) |
558 format_dict["nodes_send_sync"] += 'NODE_SEND_SYNC(%s)\n ' % (nodename) |
530 format_dict["nodes_proceed_sync"] += 'NODE_PROCEED_SYNC(%s)\n '%(nodename) |
559 format_dict["nodes_proceed_sync"] += 'NODE_PROCEED_SYNC(%s)\n ' % (nodename) |
531 |
560 |
532 # initialize and declare node boot status variables for post_SlaveBootup lookup |
561 # initialize and declare node boot status variables for post_SlaveBootup lookup |
533 SlaveIDs = child.GetSlaveIDs() |
562 SlaveIDs = child.GetSlaveIDs() |
534 if len(SlaveIDs) == 0: |
563 if len(SlaveIDs) == 0: |
535 # define post_SlaveBootup lookup functions |
564 # define post_SlaveBootup lookup functions |
536 format_dict["slavebootups"] += ( |
565 format_dict["slavebootups"] += ( |
537 "static void %s_post_SlaveBootup(CO_Data* d, UNS8 nodeId){}\n"%(nodename)) |
566 "static void %s_post_SlaveBootup(CO_Data* d, UNS8 nodeId){}\n" % (nodename)) |
538 else: |
567 else: |
539 format_dict["slavebootups"] += ( |
568 format_dict["slavebootups"] += ( |
540 "static void %s_post_SlaveBootup(CO_Data* d, UNS8 nodeId){\n"%(nodename)+ |
569 "static void %s_post_SlaveBootup(CO_Data* d, UNS8 nodeId){\n" % (nodename) + |
541 " check_and_start_node(d, nodeId);\n"+ |
570 " check_and_start_node(d, nodeId);\n" + |
542 "}\n") |
571 "}\n") |
543 # register previously declared func as post_SlaveBootup callback for that node |
572 # register previously declared func as post_SlaveBootup callback for that node |
544 format_dict["slavebootup_register"] += ( |
573 format_dict["slavebootup_register"] += ( |
545 "%s_Data.post_SlaveBootup = %s_post_SlaveBootup;\n"%(nodename,nodename)) |
574 "%s_Data.post_SlaveBootup = %s_post_SlaveBootup;\n" % (nodename, nodename)) |
546 format_dict["pre_op"] += ( |
575 format_dict["pre_op"] += ( |
547 "static void %s_preOperational(CO_Data* d){\n "%(nodename)+ |
576 "static void %s_preOperational(CO_Data* d){\n " % (nodename) + |
548 "".join([" masterSendNMTstateChange(d, %d, NMT_Reset_Comunication);\n"%NdId for NdId in SlaveIDs])+ |
577 "".join([" masterSendNMTstateChange(d, %d, NMT_Reset_Comunication);\n" % NdId for NdId in SlaveIDs]) + |
549 "}\n") |
578 "}\n") |
550 format_dict["pre_op_register"] += ( |
579 format_dict["pre_op_register"] += ( |
551 "%s_Data.preOperational = %s_preOperational;\n"%(nodename,nodename)) |
580 "%s_Data.preOperational = %s_preOperational;\n" % (nodename, nodename)) |
552 else: |
581 else: |
553 # Slave node |
582 # Slave node |
554 align = child_data.getSync_Align() |
583 align = child_data.getSync_Align() |
555 align_ratio=child_data.getSync_Align_Ratio() |
584 align_ratio = child_data.getSync_Align_Ratio() |
556 if align > 0: |
585 if align > 0: |
557 format_dict["post_sync"] += ( |
586 format_dict["post_sync"] += ( |
558 "static int %s_CalCount = 0;\n"%(nodename)+ |
587 "static int %s_CalCount = 0;\n" % (nodename) + |
559 "static void %s_post_sync(CO_Data* d){\n"%(nodename)+ |
588 "static void %s_post_sync(CO_Data* d){\n" % (nodename) + |
560 " if(%s_CalCount < %d){\n"%(nodename, align)+ |
589 " if(%s_CalCount < %d){\n" % (nodename, align) + |
561 " %s_CalCount++;\n"%(nodename)+ |
590 " %s_CalCount++;\n" % (nodename) + |
562 " align_tick(-1);\n"+ |
591 " align_tick(-1);\n" + |
563 " }else{\n"+ |
592 " }else{\n" + |
564 " align_tick(%d);\n"%(align_ratio)+ |
593 " align_tick(%d);\n" % (align_ratio) + |
565 " }\n"+ |
594 " }\n" + |
566 "}\n") |
595 "}\n") |
567 format_dict["post_sync_register"] += ( |
596 format_dict["post_sync_register"] += ( |
568 "%s_Data.post_sync = %s_post_sync;\n"%(nodename,nodename)) |
597 "%s_Data.post_sync = %s_post_sync;\n" % (nodename, nodename)) |
569 format_dict["nodes_init"] += 'NODE_SLAVE_INIT(%s, %s)\n '%( |
598 format_dict["nodes_init"] += 'NODE_SLAVE_INIT(%s, %s)\n ' % ( |
570 nodename, |
599 nodename, |
571 child_data.getNodeId()) |
600 child_data.getNodeId()) |
572 |
601 |
573 # Include generated OD headers |
602 # Include generated OD headers |
574 format_dict["nodes_includes"] += '#include "%s.h"\n'%(nodename) |
603 format_dict["nodes_includes"] += '#include "%s.h"\n' % (nodename) |
575 # Declare CAN channels according user filled config |
604 # Declare CAN channels according user filled config |
576 format_dict["board_decls"] += 'BOARD_DECL(%s, "%s", "%s")\n'%( |
605 format_dict["board_decls"] += 'BOARD_DECL(%s, "%s", "%s")\n' % ( |
577 nodename, |
606 nodename, |
578 child.GetCanDevice(), |
607 child.GetCanDevice(), |
579 child_data.getCAN_Baudrate()) |
608 child_data.getCAN_Baudrate()) |
580 format_dict["nodes_open"] += 'NODE_OPEN(%s)\n '%(nodename) |
609 format_dict["nodes_open"] += 'NODE_OPEN(%s)\n ' % (nodename) |
581 format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n '%(nodename) |
610 format_dict["nodes_close"] += 'NODE_CLOSE(%s)\n ' % (nodename) |
582 format_dict["nodes_stop"] += 'NODE_STOP(%s)\n '%(nodename) |
611 format_dict["nodes_stop"] += 'NODE_STOP(%s)\n ' % (nodename) |
583 |
612 |
584 filename = paths.AbsNeighbourFile(__file__,"cf_runtime.c") |
613 filename = paths.AbsNeighbourFile(__file__, "cf_runtime.c") |
585 cf_main = open(filename).read() % format_dict |
614 cf_main = open(filename).read() % format_dict |
586 cf_main_path = os.path.join(buildpath, "CF_%(locstr)s.c"%format_dict) |
615 cf_main_path = os.path.join(buildpath, "CF_%(locstr)s.c" % format_dict) |
587 f = open(cf_main_path,'w') |
616 f = open(cf_main_path, 'w') |
588 f.write(cf_main) |
617 f.write(cf_main) |
589 f.close() |
618 f.close() |
590 |
619 |
591 res = [(cf_main_path, local_canfestival_config.getCFLAGS(CanFestivalPath))],local_canfestival_config.getLDFLAGS(CanFestivalPath), True |
620 res = [(cf_main_path, local_canfestival_config.getCFLAGS(CanFestivalPath))], local_canfestival_config.getLDFLAGS(CanFestivalPath), True |
592 |
621 |
593 if can_driver is not None: |
622 if can_driver is not None: |
594 can_driver_path = os.path.join(CanFestivalPath,"drivers",can_driver,can_driver_name) |
623 can_driver_path = os.path.join(CanFestivalPath, "drivers", can_driver, can_driver_name) |
595 if os.path.exists(can_driver_path): |
624 if os.path.exists(can_driver_path): |
596 res += ((can_driver_name, file(can_driver_path,"rb")),) |
625 res += ((can_driver_name, file(can_driver_path, "rb")),) |
597 |
626 |
598 return res |
627 return res |
599 |
|