66 SLOGF(LOG_CRITICAL, "EtherCAT failed to get default value for output PDO in slave %(device_type)s at alias %(alias)d and position %(position)d. Error: %%ud", abort_code); |
66 SLOGF(LOG_CRITICAL, "EtherCAT failed to get default value for output PDO in slave %(device_type)s at alias %(alias)d and position %(position)d. Error: %%ud", abort_code); |
67 goto ecat_failed; |
67 goto ecat_failed; |
68 } |
68 } |
69 %(real_var)s = EC_READ_%(data_type)s((uint8_t *)value); |
69 %(real_var)s = EC_READ_%(data_type)s((uint8_t *)value); |
70 } |
70 } |
|
71 """ |
|
72 |
|
73 SLAVE_OUTPUT_PDO_DEFAULT_VALUE_BIT = """ |
|
74 { |
|
75 uint8_t value[%(data_size)d]; |
|
76 if (ecrt_master_sdo_upload(master, %(slave)d, 0x%(index).4x, 0x%(subindex).2x, (uint8_t *)value, %(data_size)d, &result_size, &abort_code)) { |
|
77 SLOGF(LOG_CRITICAL, "EtherCAT failed to get default value for output PDO in slave %(device_type)s at alias %(alias)d and position %(position)d. Error: %%ud", abort_code); |
|
78 goto ecat_failed; |
|
79 } |
|
80 %(real_var)s = EC_READ_%(data_type)s((uint8_t *)value, %(subindex)d); |
|
81 } |
|
82 """ |
|
83 |
|
84 |
|
85 SLAVE_INPUT_PDO_DEFAULT_VALUE = """ |
|
86 { |
|
87 uint8_t value[%(data_size)d]; |
|
88 if (ecrt_master_sdo_upload(master, %(slave)d, 0x%(index).4x, 0x%(subindex).2x, (uint8_t *)value, %(data_size)d, &result_size, &abort_code)) { |
|
89 SLOGF(LOG_CRITICAL, "EtherCAT failed to get default value for input PDO in slave %(device_type)s at alias %(alias)d and position %(position)d. Error: %%ud", abort_code); |
|
90 goto ecat_failed; |
|
91 } |
|
92 %(real_var)s = EC_READ_%(data_type)s((uint8_t *)value); |
|
93 } |
|
94 """ |
|
95 |
|
96 DC_VARIABLE =""" |
|
97 #define DC_ENABLE %(dc_flag)d |
|
98 """ |
|
99 |
|
100 CONFIG_DC = """ |
|
101 ecrt_slave_config_dc (slave%(slave)d, 0x0%(assign_activate)ld, %(sync0_cycle_time)d, %(sync0_shift_time)d, %(sync1_cycle_time)d, %(sync1_shift_time)d); |
71 """ |
102 """ |
72 |
103 |
73 |
104 |
74 def ConfigureVariable(entry_infos, str_completion): |
105 def ConfigureVariable(entry_infos, str_completion): |
75 entry_infos["data_type"] = DATATYPECONVERSION.get(entry_infos["var_type"], None) |
106 entry_infos["data_type"] = DATATYPECONVERSION.get(entry_infos["var_type"], None) |
190 "used_pdo_entry_offset_variables_declaration": [], |
221 "used_pdo_entry_offset_variables_declaration": [], |
191 "used_pdo_entry_configuration": [], |
222 "used_pdo_entry_configuration": [], |
192 "pdos_configuration_declaration": "", |
223 "pdos_configuration_declaration": "", |
193 "slaves_declaration": "", |
224 "slaves_declaration": "", |
194 "slaves_configuration": "", |
225 "slaves_configuration": "", |
|
226 # add jblee |
|
227 "slaves_input_pdos_default_values_extraction": "", |
195 "slaves_output_pdos_default_values_extraction": "", |
228 "slaves_output_pdos_default_values_extraction": "", |
196 "slaves_initialization": "", |
229 "slaves_initialization": "", |
197 "retrieve_variables": [], |
230 "retrieve_variables": [], |
198 "publish_variables": [], |
231 "publish_variables": [], |
|
232 #-----------This Code templete for dc -------------------# |
|
233 "dc_variable" : "", |
|
234 "config_dc": "" |
199 } |
235 } |
200 |
236 |
201 # Initialize variable storing variable mapping state |
237 # Initialize variable storing variable mapping state |
202 for slave_entries in self.UsedVariables.itervalues(): |
238 for slave_entries in self.UsedVariables.itervalues(): |
203 for entry_infos in slave_entries.itervalues(): |
239 for entry_infos in slave_entries.itervalues(): |
242 if device_coe is not None: |
281 if device_coe is not None: |
243 |
282 |
244 # If device support CanOpen over Ethernet, adding code for calling |
283 # If device support CanOpen over Ethernet, adding code for calling |
245 # init commands when initializing slave in master code template strings |
284 # init commands when initializing slave in master code template strings |
246 initCmds = [] |
285 initCmds = [] |
|
286 |
247 for initCmd in device_coe.getInitCmd(): |
287 for initCmd in device_coe.getInitCmd(): |
248 initCmds.append({ |
288 initCmds.append({ |
249 "Index": ExtractHexDecValue(initCmd.getIndex()), |
289 "Index": ExtractHexDecValue(initCmd.getIndex()), |
250 "Subindex": ExtractHexDecValue(initCmd.getSubIndex()), |
290 "Subindex": ExtractHexDecValue(initCmd.getSubIndex()), |
251 "Value": initCmd.getData().getcontent()}) |
291 #"Value": initCmd.getData().getcontent()}) |
|
292 "Value": int(initCmd.getData().text, 16)}) |
|
293 |
252 initCmds.extend(slave.getStartupCommands()) |
294 initCmds.extend(slave.getStartupCommands()) |
253 for initCmd in initCmds: |
295 for initCmd in initCmds: |
254 index = initCmd["Index"] |
296 index = initCmd["Index"] |
255 subindex = initCmd["Subindex"] |
297 subindex = initCmd["Subindex"] |
256 entry = device_entries.get((index, subindex), None) |
298 entry = device_entries.get((index, subindex), None) |
312 sync_managers.append(sync_manager_infos) |
354 sync_managers.append(sync_manager_infos) |
313 |
355 |
314 pdos_index = [] |
356 pdos_index = [] |
315 exclusive_pdos = {} |
357 exclusive_pdos = {} |
316 selected_pdos = [] |
358 selected_pdos = [] |
317 for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] + |
359 |
318 [(pdo, "Outputs") for pdo in device.getRxPdo()]): |
360 # add jblee |
319 |
361 TxPdoData = [] |
|
362 RxPdoData = [] |
|
363 PdoData = [] |
|
364 |
|
365 # add jblee |
|
366 if len(device.getTxPdo() + device.getRxPdo()) > 0: |
|
367 for pdo in device.getTxPdo(): |
|
368 PdoData.append((pdo, "Inputs")) |
|
369 for pdo in device.getRxPdo(): |
|
370 PdoData.append((pdo, "Outputs")) |
|
371 |
|
372 # mod jblee |
|
373 #for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] + |
|
374 # [(pdo, "Outputs") for pdo in device.getRxPdo()]): |
|
375 #for pdo, pdo_type in (TxPdoData + RxPdoData): |
|
376 data_files = os.listdir(self.Controler.CTNPath()) |
|
377 PDODataList = [] |
|
378 MDPData = [] |
|
379 RxPDOData = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getRxPDO() |
|
380 TxPDOData = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getTxPDO() |
|
381 PDOList = RxPDOData.split() + TxPDOData.split() |
|
382 for PDOIndex in PDOList: |
|
383 if PDOIndex in ["RxPDO", "TxPDO", "None"]: |
|
384 continue |
|
385 PDODataList.append(int(PDOIndex, 0)) |
|
386 |
|
387 # add jblee for DC Configuration |
|
388 dc_enable = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Enable() |
|
389 sync0_cycle_time = 0 |
|
390 sync0_shift_time = 0 |
|
391 sync1_cycle_time = 0 |
|
392 sync1_shift_time = 0 |
|
393 if dc_enable : |
|
394 sync0_cycle_token = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Sync0_Cycle_Time() |
|
395 if sync0_cycle_token != "None": |
|
396 sync0_cycle_time = int(sync0_cycle_token.split("_")[1]) * 1000 |
|
397 sync0_shift_token = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Sync0_Shift_Time() |
|
398 if sync0_shift_token != "None": |
|
399 sync0_shift_time = int(sync0_shift_token) * 1000 |
|
400 sync1_cycle_token = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Sync1_Cycle_Time() |
|
401 if sync1_cycle_token != "None": |
|
402 sync1_cycle_time = int(sync1_cycle_token.split("_")[1]) * 1000 |
|
403 sync1_shift_token = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Sync1_Shift_Time() |
|
404 if sync1_shift_token != "None": |
|
405 sync1_shift_time = int(sync1_shift_token) * 1000 |
|
406 |
|
407 dc_config_data = { |
|
408 "slave" : slave_idx, |
|
409 "assign_activate" : int(self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Assign_Activate()), |
|
410 "sync0_cycle_time" : sync0_cycle_time, |
|
411 "sync0_shift_time" : sync0_shift_time, |
|
412 "sync1_cycle_time" : sync1_cycle_time, |
|
413 "sync1_shift_time" : sync1_shift_time, |
|
414 } |
|
415 |
|
416 if dc_enable and not str_completion["dc_variable"] : |
|
417 str_completion["dc_variable"] += DC_VARIABLE % {"dc_flag" : dc_enable} |
|
418 str_completion["config_dc"] += CONFIG_DC % dc_config_data |
|
419 |
|
420 for data_file in data_files: |
|
421 slave_path = os.path.join(self.Controler.CTNPath(), data_file) |
|
422 if os.path.isdir(slave_path): |
|
423 CheckConfNodePath = os.path.join(slave_path, "baseconfnode.xml") |
|
424 confNodeFile = open(CheckConfNodePath, 'r') |
|
425 checklines = confNodeFile.readlines() |
|
426 confNodeFile.close() |
|
427 # checklines(ex) : <BaseParams xmlns:xsd="http://www.w3.org/2001/XMLSchema" IEC_Channel="0" Name="EthercatSlave_0"/> |
|
428 # checklines[1].split() : [<BaseParams, xmlns:xsd="http://www.w3.org/2001/XMLSchema", |
|
429 # IEC_Channel="0", Name="EthercatSlave_0"/>] |
|
430 # checklines[1].split()[2] : IEC_Channel="0" |
|
431 # checklines[1].split()[2].split("\"") = [IEC_Channel=, 0, ] |
|
432 pos_check = int(checklines[1].split()[2].split("\"")[1]) |
|
433 if slave_idx == pos_check: |
|
434 MDPDataFilePath = os.path.join(slave_path, "DataForMDP.txt") |
|
435 if os.path.isfile(MDPDataFilePath): |
|
436 MDPDataFile = open(MDPDataFilePath, 'r') |
|
437 MDPData = MDPDataFile.readlines() |
|
438 MDPDataFile.close() |
|
439 |
|
440 for MDPLine in MDPData: |
|
441 if MDPLine == "\n": |
|
442 continue |
|
443 module_pos = int(MDPLine.split()[-1]) |
|
444 module = self.Controler.CTNParent.GetSelectModule(module_pos) |
|
445 for pdo in module.getTxPdo(): |
|
446 PdoData.append((pdo, "Inputs")) |
|
447 PDODataList.append(ExtractHexDecValue(pdo.getIndex().getcontent())) |
|
448 for pdo in module.getRxPdo(): |
|
449 PdoData.append((pdo, "Outputs")) |
|
450 PDODataList.append(ExtractHexDecValue(pdo.getIndex().getcontent())) |
|
451 |
|
452 for pdo, pdo_type in PdoData: |
320 pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) |
453 pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) |
321 pdos_index.append(pdo_index) |
454 pdos_index.append(pdo_index) |
|
455 |
|
456 if PDODataList and (pdo_index in PDODataList): |
|
457 continue |
322 |
458 |
323 excluded_list = pdo.getExclude() |
459 excluded_list = pdo.getExclude() |
324 if len(excluded_list) > 0: |
460 if len(excluded_list) > 0: |
325 exclusion_list = [pdo_index] |
461 exclusion_list = [pdo_index] |
326 for excluded in excluded_list: |
462 for excluded in excluded_list: |
328 exclusion_list.sort() |
464 exclusion_list.sort() |
329 |
465 |
330 exclusion_scope = exclusive_pdos.setdefault(tuple(exclusion_list), []) |
466 exclusion_scope = exclusive_pdos.setdefault(tuple(exclusion_list), []) |
331 |
467 |
332 entries = pdo.getEntry() |
468 entries = pdo.getEntry() |
|
469 |
333 pdo_mapping_match = { |
470 pdo_mapping_match = { |
334 "index": pdo_index, |
471 "index": pdo_index, |
335 "matching": 0, |
472 "matching": 0, |
336 "count": len(entries), |
473 "count": len(entries), |
337 "assigned": pdo.getSm() is not None |
474 "assigned": pdo.getSm() is not None |
338 } |
475 } |
|
476 |
339 exclusion_scope.append(pdo_mapping_match) |
477 exclusion_scope.append(pdo_mapping_match) |
340 |
478 |
341 for entry in entries: |
479 for entry in entries: |
342 index = ExtractHexDecValue(entry.getIndex().getcontent()) |
480 index = ExtractHexDecValue(entry.getIndex().getcontent()) |
343 subindex = ExtractHexDecValue(entry.getSubIndex()) |
481 subindex = ExtractHexDecValue(entry.getSubIndex()) |
362 excluded_pdos.extend([ |
500 excluded_pdos.extend([ |
363 pdo["index"] |
501 pdo["index"] |
364 for pdo in exclusion_scope[start_excluding_index:] |
502 for pdo in exclusion_scope[start_excluding_index:] |
365 if PdoAssign or not pdo["assigned"]]) |
503 if PdoAssign or not pdo["assigned"]]) |
366 |
504 |
367 for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] + |
505 # mod jblee |
368 [(pdo, "Outputs") for pdo in device.getRxPdo()]): |
506 #for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] + |
369 entries = pdo.getEntry() |
507 # [(pdo, "Outputs") for pdo in device.getRxPdo()]): |
370 |
508 #for pdo, pdo_type in (TxPdoData + RxPdoData): |
|
509 entry_check_list = [] |
|
510 index_padding = 1 |
|
511 for pdo, pdo_type in PdoData: |
|
512 entries = pdo.getEntry() |
|
513 |
371 pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) |
514 pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) |
372 if pdo_index in excluded_pdos: |
515 if pdo_index in excluded_pdos: |
373 continue |
516 continue |
374 |
517 if PDODataList and (pdo_index not in PDODataList): |
375 pdo_needed = pdo_index in selected_pdos |
518 continue |
376 |
519 |
377 entries_infos = [] |
520 #pdo_needed = pdo_index in selected_pdos |
378 |
521 pdo_needed = pdo_index in PDODataList |
|
522 |
|
523 if len(MDPData) > 0: |
|
524 pdo_index += index_padding |
|
525 index_padding += 1 |
|
526 |
|
527 entries_infos = [] |
379 for entry in entries: |
528 for entry in entries: |
380 index = ExtractHexDecValue(entry.getIndex().getcontent()) |
529 index = ExtractHexDecValue(entry.getIndex().getcontent()) |
381 subindex = ExtractHexDecValue(entry.getSubIndex()) |
530 subindex = ExtractHexDecValue(entry.getSubIndex()) |
|
531 |
|
532 # add jblee |
|
533 if len(MDPData) > 0: |
|
534 increse = self.Controler.CTNParent.GetMDPInfos(type_infos) |
|
535 if increse and index != 0: |
|
536 index += int(increse[0][2]) * slotNumber |
|
537 |
382 entry_infos = { |
538 entry_infos = { |
383 "index": index, |
539 "index": index, |
384 "subindex": subindex, |
540 "subindex": subindex, |
385 "name": ExtractName(entry.getName()), |
541 "name": ExtractName(entry.getName()), |
386 "bitlen": entry.getBitLen(), |
542 "bitlen": entry.getBitLen(), |
387 } |
543 } |
|
544 |
|
545 entry_infos.update(type_infos) |
|
546 #temp_data = " {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos |
|
547 check_data = "{0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}" % entry_infos |
|
548 if entry_check_list and check_data in entry_check_list: |
|
549 if (entry_infos["index"] == 0) or (entry_infos["name"] == None): |
|
550 pass |
|
551 else: |
388 entry_infos.update(type_infos) |
552 entry_infos.update(type_infos) |
389 entries_infos.append(" {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos) |
553 entries_infos.append(" {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos) |
390 |
554 entry_check_list.append(check_data) |
|
555 |
391 entry_declaration = slave_variables.get((index, subindex), None) |
556 entry_declaration = slave_variables.get((index, subindex), None) |
392 if entry_declaration is not None and not entry_declaration["mapped"]: |
557 if entry_declaration is not None and not entry_declaration["mapped"]: |
393 pdo_needed = True |
558 pdo_needed = True |
394 |
559 |
395 entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"], |
560 entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"], |
419 entry_infos["var_type"] = data_type |
584 entry_infos["var_type"] = data_type |
420 entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos |
585 entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos |
421 |
586 |
422 ConfigureVariable(entry_infos, str_completion) |
587 ConfigureVariable(entry_infos, str_completion) |
423 |
588 |
424 str_completion["slaves_output_pdos_default_values_extraction"] += \ |
589 if entry_infos["data_type"] == "BIT" : |
425 SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos |
590 str_completion["slaves_output_pdos_default_values_extraction"] += \ |
426 |
591 SLAVE_OUTPUT_PDO_DEFAULT_VALUE_BIT % entry_infos |
|
592 else : |
|
593 str_completion["slaves_output_pdos_default_values_extraction"] += \ |
|
594 SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos |
|
595 |
|
596 elif pdo_type == "Inputs" and entry.getDataType() is not None and device_coe is not None: |
|
597 data_type = entry.getDataType().getcontent() |
|
598 entry_infos["dir"] = "I" |
|
599 entry_infos["data_size"] = max(1, entry_infos["bitlen"] / 8) |
|
600 entry_infos["data_type"] = DATATYPECONVERSION.get(data_type) |
|
601 entry_infos["var_type"] = data_type |
|
602 entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos |
|
603 |
|
604 ConfigureVariable(entry_infos, str_completion) |
|
605 |
|
606 str_completion["slaves_input_pdos_default_values_extraction"] += \ |
|
607 SLAVE_INPUT_PDO_DEFAULT_VALUE % entry_infos |
|
608 |
427 if pdo_needed: |
609 if pdo_needed: |
428 for excluded in pdo.getExclude(): |
610 for excluded in pdo.getExclude(): |
429 excluded_index = ExtractHexDecValue(excluded.getcontent()) |
611 excluded_index = ExtractHexDecValue(excluded.getcontent()) |
430 if excluded_index not in excluded_pdos: |
612 if excluded_index not in excluded_pdos: |
431 excluded_pdos.append(excluded_index) |
613 excluded_pdos.append(excluded_index) |
446 "type": pdo_type, |
628 "type": pdo_type, |
447 "entries": entries_infos, |
629 "entries": entries_infos, |
448 "entries_number": len(entries_infos), |
630 "entries_number": len(entries_infos), |
449 "fixed": pdo.getFixed() is True}) |
631 "fixed": pdo.getFixed() is True}) |
450 |
632 |
|
633 # for MDP |
|
634 slotNumber += 1 |
|
635 |
451 if PdoConfig and PdoAssign: |
636 if PdoConfig and PdoAssign: |
452 dynamic_pdos = {} |
637 dynamic_pdos = {} |
453 dynamic_pdos_number = 0 |
638 dynamic_pdos_number = 0 |
454 for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), |
639 for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), |
455 ("Outputs", 0x1a00, 0x1C00)]: |
640 ("Outputs", 0x1a00, 0x1C00)]: |
562 |
747 |
563 for element in ["pdos_entries_infos", "pdos_infos", "pdos_sync_infos"]: |
748 for element in ["pdos_entries_infos", "pdos_infos", "pdos_sync_infos"]: |
564 pdos_infos[element] = "\n".join(pdos_infos[element]) |
749 pdos_infos[element] = "\n".join(pdos_infos[element]) |
565 |
750 |
566 str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos |
751 str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos |
567 |
752 |
568 for (index, subindex), entry_declaration in slave_variables.iteritems(): |
753 #for (index, subindex), entry_declaration in slave_variables.iteritems(): |
569 if not entry_declaration["mapped"]: |
754 # if not entry_declaration["mapped"]: |
570 message = _("Entry index 0x{a1:.4x}, subindex 0x{a2:.2x} not mapped for device {a3}").\ |
755 # message = _("Entry index 0x%4.4x, subindex 0x%2.2x not mapped for device %s") % \ |
571 format(a1=index, a2=subindex, a3=type_infos["device_type"]) |
756 # (index, subindex, type_infos["device_type"]) |
572 self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n") |
757 # self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n") |
573 |
758 |
574 for element in ["used_pdo_entry_offset_variables_declaration", |
759 for element in ["used_pdo_entry_offset_variables_declaration", |
575 "used_pdo_entry_configuration", |
760 "used_pdo_entry_configuration", |
576 "located_variables_declaration", |
761 "located_variables_declaration", |
577 "retrieve_variables", |
762 "retrieve_variables", |
578 "publish_variables"]: |
763 "publish_variables"]: |
579 str_completion[element] = "\n".join(str_completion[element]) |
764 str_completion[element] = "\n".join(str_completion[element]) |
580 |
765 |
581 etherlabfile = open(filepath, 'w') |
766 etherlabfile = open(filepath, 'w') |
582 etherlabfile.write(plc_etherlab_code % str_completion) |
767 etherlabfile.write(plc_etherlab_code % str_completion) |