etherlab/etherlab.py
changeset 2082 caae3ad2d03b
parent 2081 b1801bf4365c
child 2083 0f7ab170c862
equal deleted inserted replaced
2081:b1801bf4365c 2082:caae3ad2d03b
   792                  "slave%(slave)d_%(index).4x_%(subindex).2x);") % entry_infos)
   792                  "slave%(slave)d_%(index).4x_%(subindex).2x);") % entry_infos)
   793         elif entry_infos["dir"] == "Q":
   793         elif entry_infos["dir"] == "Q":
   794             str_completion["publish_variables"].append(
   794             str_completion["publish_variables"].append(
   795                 ("    EC_WRITE_%(data_type)s(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " + 
   795                 ("    EC_WRITE_%(data_type)s(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " + 
   796                  "%(real_var)s);") % entry_infos)
   796                  "%(real_var)s);") % entry_infos)
       
   797 
       
   798 def ExclusionSortFunction(x, y):
       
   799     if x["matching"] == y["matching"]:
       
   800         if x["assigned"] and not y["assigned"]:
       
   801             return -1
       
   802         elif not x["assigned"] and y["assigned"]:
       
   803             return 1
       
   804         return cmp(x["count"], y["count"])
       
   805     return -cmp(x["matching"], y["matching"])
   797 
   806 
   798 class _EthercatCFileGenerator:
   807 class _EthercatCFileGenerator:
   799     
   808     
   800     def __init__(self, controler):
   809     def __init__(self, controler):
   801         self.Controler = controler
   810         self.Controler = controler
   945                             sync_manager_infos["watchdog"] = "EC_WD_DISABLE"
   954                             sync_manager_infos["watchdog"] = "EC_WD_DISABLE"
   946                         
   955                         
   947                         sync_managers.append(sync_manager_infos)
   956                         sync_managers.append(sync_manager_infos)
   948                     
   957                     
   949                     pdos_index = []
   958                     pdos_index = []
   950                     excluded_pdos = []
   959                     exclusive_pdos = {}
   951                     for only_mandatory in [True, False]:
   960                     selected_pdos = []
   952                         for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
   961                     for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
   953                                               [(pdo, "Outputs") for pdo in device.getRxPdo()]):
   962                                           [(pdo, "Outputs") for pdo in device.getRxPdo()]):
       
   963                         
       
   964                         pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   965                         pdos_index.append(pdo_index)
       
   966                         
       
   967                         excluded_list = pdo.getExclude()
       
   968                         if len(excluded_list) > 0:
       
   969                             exclusion_list = [pdo_index]
       
   970                             for excluded in excluded_list:
       
   971                                 exclusion_list.append(ExtractHexDecValue(excluded.getcontent()))
       
   972                             exclusion_list.sort()
       
   973                             
       
   974                             exclusion_scope = exclusive_pdos.setdefault(tuple(exclusion_list), [])
       
   975                             
   954                             entries = pdo.getEntry()
   976                             entries = pdo.getEntry()
   955                             
   977                             pdo_mapping_match = {
   956                             pdo_needed = pdo.getMandatory()
   978                                 "index": pdo_index, 
   957                             if pdo_needed is None:
   979                                 "matching": 0, 
   958                                 pdo_needed = False
   980                                 "count": len(entries), 
   959                             if only_mandatory != pdo_needed:
   981                                 "assigned": pdo.getSm() is not None
   960                                 continue
   982                             }
   961                             
   983                             exclusion_scope.append(pdo_mapping_match)
   962                             pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   963                             pdos_index.append(pdo_index)
       
   964                             if pdo_index in excluded_pdos:
       
   965                                 continue
       
   966                             
       
   967                             entries_infos = []
       
   968                             
   984                             
   969                             for entry in entries:
   985                             for entry in entries:
   970                                 index = ExtractHexDecValue(entry.getIndex().getcontent())
   986                                 index = ExtractHexDecValue(entry.getIndex().getcontent())
   971                                 subindex = ExtractHexDecValue(entry.getSubIndex())
   987                                 subindex = ExtractHexDecValue(entry.getSubIndex())
   972                                 entry_infos = {
   988                                 if slave_variables.get((index, subindex), None) is not None:
   973                                     "index": index,
   989                                     pdo_mapping_match["matching"] += 1
   974                                     "subindex": subindex,
   990                         
   975                                     "name": ExtractName(entry.getName()),
   991                         elif pdo.getMandatory():
   976                                     "bitlen": entry.getBitLen(),
   992                             selected_pdos.append(pdo_index)
   977                                 }
       
   978                                 entry_infos.update(type_infos)
       
   979                                 entries_infos.append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
       
   980                                 
       
   981                                 entry_declaration = slave_variables.get((index, subindex), None)
       
   982                                 if entry_declaration is not None and not entry_declaration["mapped"]:
       
   983                                     pdo_needed = True
       
   984                                     
       
   985                                     entry_infos.update(dict(zip(["var_type", "dir", "var_name"], entry_declaration["infos"])))
       
   986                                     entry_declaration["mapped"] = True
       
   987                                     
       
   988                                     entry_type = entry.getDataType().getcontent()
       
   989                                     if entry_infos["var_type"] != entry_type:
       
   990                                         message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
       
   991                                         if (self.Controler.GetSizeOfType(entry_infos["var_type"]) != 
       
   992                                             self.Controler.GetSizeOfType(entry_type)):
       
   993                                             raise ValueError, message
       
   994                                         else:
       
   995                                             self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
       
   996                                     
       
   997                                     if (entry_infos["dir"] == "I" and pdo_type != "Inputs" or 
       
   998                                         entry_infos["dir"] == "Q" and pdo_type != "Outputs"):
       
   999                                         raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
       
  1000                                     
       
  1001                                     ConfigureVariable(entry_infos, str_completion)
       
  1002                                 
       
  1003                                 elif pdo_type == "Outputs" and entry.getDataType() is not None and device_coe is not None:
       
  1004                                     data_type = entry.getDataType().getcontent()
       
  1005                                     entry_infos["dir"] = "Q"
       
  1006                                     entry_infos["data_size"] = max(1, entry_infos["bitlen"] / 8)
       
  1007                                     entry_infos["data_type"] = DATATYPECONVERSION.get(data_type)
       
  1008                                     entry_infos["var_type"] = data_type
       
  1009                                     entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos
       
  1010                                     
       
  1011                                     ConfigureVariable(entry_infos, str_completion)
       
  1012                                     
       
  1013                                     str_completion["slaves_output_pdos_default_values_extraction"] += \
       
  1014                                         SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos
       
  1015                                     
       
  1016                             if pdo_needed:
       
  1017                                 for excluded in pdo.getExclude():
       
  1018                                     excluded_index = ExtractHexDecValue(excluded.getcontent())
       
  1019                                     if excluded_index not in excluded_pdos:
       
  1020                                         excluded_pdos.append(excluded_index)
       
  1021                                 
       
  1022                                 sm = pdo.getSm()
       
  1023                                 if sm is None:
       
  1024                                     for sm_idx, sync_manager in enumerate(sync_managers):
       
  1025                                         if sync_manager["name"] == pdo_type:
       
  1026                                             sm = sm_idx
       
  1027                                 if sm is None:
       
  1028                                     raise ValueError, _("No sync manager available for %s pdo!") % pdo_type
       
  1029                                     
       
  1030                                 sync_managers[sm]["pdos_number"] += 1
       
  1031                                 sync_managers[sm]["pdos"].append(
       
  1032                                     {"slave": slave_idx,
       
  1033                                      "index": pdo_index,
       
  1034                                      "name": ExtractName(pdo.getName()),
       
  1035                                      "type": pdo_type, 
       
  1036                                      "entries": entries_infos,
       
  1037                                      "entries_number": len(entries_infos),
       
  1038                                      "fixed": pdo.getFixed() == True})
       
  1039                     
   993                     
       
   994                     excluded_pdos = []
       
   995                     for exclusion_scope in exclusive_pdos.itervalues():
       
   996                         exclusion_scope.sort(ExclusionSortFunction)
       
   997                         start_excluding_index = 0
       
   998                         if exclusion_scope[0]["matching"] > 0:
       
   999                             selected_pdos.append(exclusion_scope[0]["index"])
       
  1000                             start_excluding_index = 1
       
  1001                         excluded_pdos.extend([pdo["index"] for pdo in exclusion_scope[start_excluding_index:] if PdoAssign or not pdo["assigned"]])
       
  1002                     
       
  1003                     for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
       
  1004                                           [(pdo, "Outputs") for pdo in device.getRxPdo()]):
       
  1005                         entries = pdo.getEntry()
       
  1006                         
       
  1007                         pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
  1008                         if pdo_index in excluded_pdos:
       
  1009                             continue
       
  1010                         
       
  1011                         pdo_needed = pdo_index in selected_pdos
       
  1012                         
       
  1013                         entries_infos = []
       
  1014                         
       
  1015                         for entry in entries:
       
  1016                             index = ExtractHexDecValue(entry.getIndex().getcontent())
       
  1017                             subindex = ExtractHexDecValue(entry.getSubIndex())
       
  1018                             entry_infos = {
       
  1019                                 "index": index,
       
  1020                                 "subindex": subindex,
       
  1021                                 "name": ExtractName(entry.getName()),
       
  1022                                 "bitlen": entry.getBitLen(),
       
  1023                             }
       
  1024                             entry_infos.update(type_infos)
       
  1025                             entries_infos.append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
       
  1026                             
       
  1027                             entry_declaration = slave_variables.get((index, subindex), None)
       
  1028                             if entry_declaration is not None and not entry_declaration["mapped"]:
       
  1029                                 pdo_needed = True
       
  1030                                 
       
  1031                                 entry_infos.update(dict(zip(["var_type", "dir", "var_name"], entry_declaration["infos"])))
       
  1032                                 entry_declaration["mapped"] = True
       
  1033                                 
       
  1034                                 entry_type = entry.getDataType().getcontent()
       
  1035                                 if entry_infos["var_type"] != entry_type:
       
  1036                                     message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
       
  1037                                     if (self.Controler.GetSizeOfType(entry_infos["var_type"]) != 
       
  1038                                         self.Controler.GetSizeOfType(entry_type)):
       
  1039                                         raise ValueError, message
       
  1040                                     else:
       
  1041                                         self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
       
  1042                                 
       
  1043                                 if (entry_infos["dir"] == "I" and pdo_type != "Inputs" or 
       
  1044                                     entry_infos["dir"] == "Q" and pdo_type != "Outputs"):
       
  1045                                     raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
       
  1046                                 
       
  1047                                 ConfigureVariable(entry_infos, str_completion)
       
  1048                             
       
  1049                             elif pdo_type == "Outputs" and entry.getDataType() is not None and device_coe is not None:
       
  1050                                 data_type = entry.getDataType().getcontent()
       
  1051                                 entry_infos["dir"] = "Q"
       
  1052                                 entry_infos["data_size"] = max(1, entry_infos["bitlen"] / 8)
       
  1053                                 entry_infos["data_type"] = DATATYPECONVERSION.get(data_type)
       
  1054                                 entry_infos["var_type"] = data_type
       
  1055                                 entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos
       
  1056                                 
       
  1057                                 ConfigureVariable(entry_infos, str_completion)
       
  1058                                 
       
  1059                                 str_completion["slaves_output_pdos_default_values_extraction"] += \
       
  1060                                     SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos
       
  1061                                 
       
  1062                         if pdo_needed:
       
  1063                             for excluded in pdo.getExclude():
       
  1064                                 excluded_index = ExtractHexDecValue(excluded.getcontent())
       
  1065                                 if excluded_index not in excluded_pdos:
       
  1066                                     excluded_pdos.append(excluded_index)
       
  1067                             
       
  1068                             sm = pdo.getSm()
       
  1069                             if sm is None:
       
  1070                                 for sm_idx, sync_manager in enumerate(sync_managers):
       
  1071                                     if sync_manager["name"] == pdo_type:
       
  1072                                         sm = sm_idx
       
  1073                             if sm is None:
       
  1074                                 raise ValueError, _("No sync manager available for %s pdo!") % pdo_type
       
  1075                                 
       
  1076                             sync_managers[sm]["pdos_number"] += 1
       
  1077                             sync_managers[sm]["pdos"].append(
       
  1078                                 {"slave": slave_idx,
       
  1079                                  "index": pdo_index,
       
  1080                                  "name": ExtractName(pdo.getName()),
       
  1081                                  "type": pdo_type, 
       
  1082                                  "entries": entries_infos,
       
  1083                                  "entries_number": len(entries_infos),
       
  1084                                  "fixed": pdo.getFixed() == True})
       
  1085                 
  1040                     if PdoConfig and PdoAssign:
  1086                     if PdoConfig and PdoAssign:
  1041                         dynamic_pdos = {}
  1087                         dynamic_pdos = {}
  1042                         dynamic_pdos_number = 0
  1088                         dynamic_pdos_number = 0
  1043                         for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), 
  1089                         for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), 
  1044                                                                ("Outputs", 0x1a00, 0x1C00)]:
  1090                                                                ("Outputs", 0x1a00, 0x1C00)]: