etherlab/EthercatCFileGenerator.py
changeset 2144 bbd78ac226d0
parent 2140 56643934495c
child 2165 02a2b5dee5e3
equal deleted inserted replaced
2143:83a2e3db4c8c 2144:bbd78ac226d0
   200                 alias[slave_alias] = 0
   200                 alias[slave_alias] = 0
   201             slave_pos = (slave_alias, alias[slave_alias])
   201             slave_pos = (slave_alias, alias[slave_alias])
   202             
   202             
   203             # Extract slave device informations
   203             # Extract slave device informations
   204             device, module_extra_params = self.Controler.GetModuleInfos(type_infos)
   204             device, module_extra_params = self.Controler.GetModuleInfos(type_infos)
   205             if device is not None:
   205             if device is None:
   206                 
   206                 raise ValueError, _("No informations found for device %s!") % (type_infos["device_type"])
   207                 # Extract slaves variables to be mapped
   207             
   208                 slave_variables = self.UsedVariables.get(slave_idx, {})
   208             # Extract slaves variables to be mapped
   209                 
   209             slave_variables = self.UsedVariables.get(slave_idx, {})
   210                 # Extract slave device object dictionary entries
   210             
   211                 device_entries = device.GetEntriesList()
   211             # Extract slave device object dictionary entries
   212                 
   212             device_entries = device.GetEntriesList()
   213                 # Adding code for declaring slave in master code template strings
   213             
   214                 for element in ["vendor", "product_code", "revision_number"]:
   214             # Adding code for declaring slave in master code template strings
   215                     type_infos[element] = ExtractHexDecValue(type_infos[element])
   215             for element in ["vendor", "product_code", "revision_number"]:
   216                 type_infos.update(dict(zip(["slave", "alias", "position"], (slave_idx,) + slave_pos)))
   216                 type_infos[element] = ExtractHexDecValue(type_infos[element])
   217                 
   217             type_infos.update(dict(zip(["slave", "alias", "position"], (slave_idx,) + slave_pos)))
   218                 # Extract slave device CoE informations
   218             
   219                 device_coe = device.getCoE()
   219             # Extract slave device CoE informations
   220                 if device_coe is not None:
   220             device_coe = device.getCoE()
   221                     
   221             if device_coe is not None:
   222                     # If device support CanOpen over Ethernet, adding code for calling 
   222                 
   223                     # init commands when initializing slave in master code template strings
   223                 # If device support CanOpen over Ethernet, adding code for calling 
   224                     initCmds = []
   224                 # init commands when initializing slave in master code template strings
   225                     for initCmd in device_coe.getInitCmd():
   225                 initCmds = []
   226                         initCmds.append({
   226                 for initCmd in device_coe.getInitCmd():
   227                             "Index": ExtractHexDecValue(initCmd.getIndex()),
   227                     initCmds.append({
   228                             "Subindex": ExtractHexDecValue(initCmd.getSubIndex()),
   228                         "Index": ExtractHexDecValue(initCmd.getIndex()),
   229                             "Value": initCmd.getData().getcontent()})
   229                         "Subindex": ExtractHexDecValue(initCmd.getSubIndex()),
   230                     initCmds.extend(slave.getStartupCommands())
   230                         "Value": initCmd.getData().getcontent()})
   231                     for initCmd in initCmds:
   231                 initCmds.extend(slave.getStartupCommands())
   232                         index = initCmd["Index"]
   232                 for initCmd in initCmds:
   233                         subindex = initCmd["Subindex"]
   233                     index = initCmd["Index"]
   234                         entry = device_entries.get((index, subindex), None)
   234                     subindex = initCmd["Subindex"]
   235                         if entry is not None:
   235                     entry = device_entries.get((index, subindex), None)
   236                             data_size = entry["BitSize"] / 8
   236                     if entry is not None:
   237                             data_str = ("0x%%.%dx" % (data_size * 2)) % initCmd["Value"]
   237                         data_size = entry["BitSize"] / 8
   238                             init_cmd_infos = {
   238                         data_str = ("0x%%.%dx" % (data_size * 2)) % initCmd["Value"]
   239                                 "index": index,
   239                         init_cmd_infos = {
   240                                 "subindex": subindex,
   240                             "index": index,
   241                                 "data": data_str,
   241                             "subindex": subindex,
   242                                 "data_type": DATATYPECONVERSION.get(entry["Type"]),
   242                             "data": data_str,
   243                                 "data_size": data_size
   243                             "data_type": DATATYPECONVERSION.get(entry["Type"]),
   244                             }
   244                             "data_size": data_size
   245                             init_cmd_infos.update(type_infos)
   245                         }
   246                             str_completion["slaves_initialization"] += SLAVE_INITIALIZATION_TEMPLATE % init_cmd_infos
   246                         init_cmd_infos.update(type_infos)
   247                 
   247                         str_completion["slaves_initialization"] += SLAVE_INITIALIZATION_TEMPLATE % init_cmd_infos
   248                     # Extract slave device PDO configuration capabilities
   248             
   249                     PdoAssign = device_coe.getPdoAssign()
   249                 # Extract slave device PDO configuration capabilities
   250                     PdoConfig = device_coe.getPdoConfig()
   250                 PdoAssign = device_coe.getPdoAssign()
   251                 else:
   251                 PdoConfig = device_coe.getPdoConfig()
   252                     PdoAssign = PdoConfig = False
   252             else:
   253                 
   253                 PdoAssign = PdoConfig = False
   254                 # Test if slave has a configuration or need one
   254             
   255                 if len(device.getTxPdo() + device.getRxPdo()) > 0 or len(slave_variables) > 0 and PdoConfig and PdoAssign:
   255             # Test if slave has a configuration or need one
   256                     
   256             if len(device.getTxPdo() + device.getRxPdo()) > 0 or len(slave_variables) > 0 and PdoConfig and PdoAssign:
   257                     str_completion["slaves_declaration"] += "static ec_slave_config_t *slave%(slave)d = NULL;\n" % type_infos
   257                 
   258                     str_completion["slaves_configuration"] += SLAVE_CONFIGURATION_TEMPLATE % type_infos
   258                 str_completion["slaves_declaration"] += "static ec_slave_config_t *slave%(slave)d = NULL;\n" % type_infos
   259                     
   259                 str_completion["slaves_configuration"] += SLAVE_CONFIGURATION_TEMPLATE % type_infos
   260                     # Initializing 
   260                 
   261                     pdos_infos = {
   261                 # Initializing 
   262                         "pdos_entries_infos": [],
   262                 pdos_infos = {
   263                         "pdos_infos": [],
   263                     "pdos_entries_infos": [],
   264                         "pdos_sync_infos": [], 
   264                     "pdos_infos": [],
       
   265                     "pdos_sync_infos": [], 
       
   266                 }
       
   267                 pdos_infos.update(type_infos)
       
   268                 
       
   269                 sync_managers = []
       
   270                 for sync_manager_idx, sync_manager in enumerate(device.getSm()):
       
   271                     sync_manager_infos = {
       
   272                         "index": sync_manager_idx, 
       
   273                         "name": sync_manager.getcontent(),
       
   274                         "slave": slave_idx,
       
   275                         "pdos": [], 
       
   276                         "pdos_number": 0,
   265                     }
   277                     }
   266                     pdos_infos.update(type_infos)
   278                     
   267                     
   279                     sync_manager_control_byte = ExtractHexDecValue(sync_manager.getControlByte())
   268                     sync_managers = []
   280                     sync_manager_direction = sync_manager_control_byte & 0x0c
   269                     for sync_manager_idx, sync_manager in enumerate(device.getSm()):
   281                     sync_manager_watchdog = sync_manager_control_byte & 0x40
   270                         sync_manager_infos = {
   282                     if sync_manager_direction:
   271                             "index": sync_manager_idx, 
   283                         sync_manager_infos["sync_manager_type"] = "EC_DIR_OUTPUT"
   272                             "name": sync_manager.getcontent(),
   284                     else:
   273                             "slave": slave_idx,
   285                         sync_manager_infos["sync_manager_type"] = "EC_DIR_INPUT"
   274                             "pdos": [], 
   286                     if sync_manager_watchdog:
   275                             "pdos_number": 0,
   287                         sync_manager_infos["watchdog"] = "EC_WD_ENABLE"
       
   288                     else:
       
   289                         sync_manager_infos["watchdog"] = "EC_WD_DISABLE"
       
   290                     
       
   291                     sync_managers.append(sync_manager_infos)
       
   292                 
       
   293                 pdos_index = []
       
   294                 exclusive_pdos = {}
       
   295                 selected_pdos = []
       
   296                 for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
       
   297                                       [(pdo, "Outputs") for pdo in device.getRxPdo()]):
       
   298                     
       
   299                     pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   300                     pdos_index.append(pdo_index)
       
   301                     
       
   302                     excluded_list = pdo.getExclude()
       
   303                     if len(excluded_list) > 0:
       
   304                         exclusion_list = [pdo_index]
       
   305                         for excluded in excluded_list:
       
   306                             exclusion_list.append(ExtractHexDecValue(excluded.getcontent()))
       
   307                         exclusion_list.sort()
       
   308                         
       
   309                         exclusion_scope = exclusive_pdos.setdefault(tuple(exclusion_list), [])
       
   310                         
       
   311                         entries = pdo.getEntry()
       
   312                         pdo_mapping_match = {
       
   313                             "index": pdo_index, 
       
   314                             "matching": 0, 
       
   315                             "count": len(entries), 
       
   316                             "assigned": pdo.getSm() is not None
   276                         }
   317                         }
   277                         
   318                         exclusion_scope.append(pdo_mapping_match)
   278                         sync_manager_control_byte = ExtractHexDecValue(sync_manager.getControlByte())
       
   279                         sync_manager_direction = sync_manager_control_byte & 0x0c
       
   280                         sync_manager_watchdog = sync_manager_control_byte & 0x40
       
   281                         if sync_manager_direction:
       
   282                             sync_manager_infos["sync_manager_type"] = "EC_DIR_OUTPUT"
       
   283                         else:
       
   284                             sync_manager_infos["sync_manager_type"] = "EC_DIR_INPUT"
       
   285                         if sync_manager_watchdog:
       
   286                             sync_manager_infos["watchdog"] = "EC_WD_ENABLE"
       
   287                         else:
       
   288                             sync_manager_infos["watchdog"] = "EC_WD_DISABLE"
       
   289                         
       
   290                         sync_managers.append(sync_manager_infos)
       
   291                     
       
   292                     pdos_index = []
       
   293                     exclusive_pdos = {}
       
   294                     selected_pdos = []
       
   295                     for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
       
   296                                           [(pdo, "Outputs") for pdo in device.getRxPdo()]):
       
   297                         
       
   298                         pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   299                         pdos_index.append(pdo_index)
       
   300                         
       
   301                         excluded_list = pdo.getExclude()
       
   302                         if len(excluded_list) > 0:
       
   303                             exclusion_list = [pdo_index]
       
   304                             for excluded in excluded_list:
       
   305                                 exclusion_list.append(ExtractHexDecValue(excluded.getcontent()))
       
   306                             exclusion_list.sort()
       
   307                             
       
   308                             exclusion_scope = exclusive_pdos.setdefault(tuple(exclusion_list), [])
       
   309                             
       
   310                             entries = pdo.getEntry()
       
   311                             pdo_mapping_match = {
       
   312                                 "index": pdo_index, 
       
   313                                 "matching": 0, 
       
   314                                 "count": len(entries), 
       
   315                                 "assigned": pdo.getSm() is not None
       
   316                             }
       
   317                             exclusion_scope.append(pdo_mapping_match)
       
   318                             
       
   319                             for entry in entries:
       
   320                                 index = ExtractHexDecValue(entry.getIndex().getcontent())
       
   321                                 subindex = ExtractHexDecValue(entry.getSubIndex())
       
   322                                 if slave_variables.get((index, subindex), None) is not None:
       
   323                                     pdo_mapping_match["matching"] += 1
       
   324                         
       
   325                             if pdo.getFixed() != True:
       
   326                                 pdo_mapping_match["matching"] += \
       
   327                                     module_extra_params["max_pdo_size"] - \
       
   328                                     pdo_mapping_match["count"]
       
   329                         
       
   330                         elif pdo.getMandatory():
       
   331                             selected_pdos.append(pdo_index)
       
   332                     
       
   333                     excluded_pdos = []
       
   334                     for exclusion_scope in exclusive_pdos.itervalues():
       
   335                         exclusion_scope.sort(ExclusionSortFunction)
       
   336                         start_excluding_index = 0
       
   337                         if exclusion_scope[0]["matching"] > 0:
       
   338                             selected_pdos.append(exclusion_scope[0]["index"])
       
   339                             start_excluding_index = 1
       
   340                         excluded_pdos.extend([pdo["index"] 
       
   341                             for pdo in exclusion_scope[start_excluding_index:] 
       
   342                             if PdoAssign or not pdo["assigned"]])
       
   343                     
       
   344                     for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
       
   345                                           [(pdo, "Outputs") for pdo in device.getRxPdo()]):
       
   346                         entries = pdo.getEntry()
       
   347                         
       
   348                         pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   349                         if pdo_index in excluded_pdos:
       
   350                             continue
       
   351                         
       
   352                         pdo_needed = pdo_index in selected_pdos
       
   353                         
       
   354                         entries_infos = []
       
   355                         
   319                         
   356                         for entry in entries:
   320                         for entry in entries:
   357                             index = ExtractHexDecValue(entry.getIndex().getcontent())
   321                             index = ExtractHexDecValue(entry.getIndex().getcontent())
   358                             subindex = ExtractHexDecValue(entry.getSubIndex())
   322                             subindex = ExtractHexDecValue(entry.getSubIndex())
       
   323                             if slave_variables.get((index, subindex), None) is not None:
       
   324                                 pdo_mapping_match["matching"] += 1
       
   325                     
       
   326                         if pdo.getFixed() != True:
       
   327                             pdo_mapping_match["matching"] += \
       
   328                                 module_extra_params["max_pdo_size"] - \
       
   329                                 pdo_mapping_match["count"]
       
   330                     
       
   331                     elif pdo.getMandatory():
       
   332                         selected_pdos.append(pdo_index)
       
   333                 
       
   334                 excluded_pdos = []
       
   335                 for exclusion_scope in exclusive_pdos.itervalues():
       
   336                     exclusion_scope.sort(ExclusionSortFunction)
       
   337                     start_excluding_index = 0
       
   338                     if exclusion_scope[0]["matching"] > 0:
       
   339                         selected_pdos.append(exclusion_scope[0]["index"])
       
   340                         start_excluding_index = 1
       
   341                     excluded_pdos.extend([pdo["index"] 
       
   342                         for pdo in exclusion_scope[start_excluding_index:] 
       
   343                         if PdoAssign or not pdo["assigned"]])
       
   344                 
       
   345                 for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
       
   346                                       [(pdo, "Outputs") for pdo in device.getRxPdo()]):
       
   347                     entries = pdo.getEntry()
       
   348                     
       
   349                     pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   350                     if pdo_index in excluded_pdos:
       
   351                         continue
       
   352                     
       
   353                     pdo_needed = pdo_index in selected_pdos
       
   354                     
       
   355                     entries_infos = []
       
   356                     
       
   357                     for entry in entries:
       
   358                         index = ExtractHexDecValue(entry.getIndex().getcontent())
       
   359                         subindex = ExtractHexDecValue(entry.getSubIndex())
       
   360                         entry_infos = {
       
   361                             "index": index,
       
   362                             "subindex": subindex,
       
   363                             "name": ExtractName(entry.getName()),
       
   364                             "bitlen": entry.getBitLen(),
       
   365                         }
       
   366                         entry_infos.update(type_infos)
       
   367                         entries_infos.append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
       
   368                         
       
   369                         entry_declaration = slave_variables.get((index, subindex), None)
       
   370                         if entry_declaration is not None and not entry_declaration["mapped"]:
       
   371                             pdo_needed = True
       
   372                             
       
   373                             entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"], 
       
   374                                                         entry_declaration["infos"])))
       
   375                             entry_declaration["mapped"] = True
       
   376                             
       
   377                             entry_type = entry.getDataType().getcontent()
       
   378                             if entry_infos["var_type"] != entry_type:
       
   379                                 message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
       
   380                                 if (self.Controler.GetSizeOfType(entry_infos["var_type"]) != 
       
   381                                     self.Controler.GetSizeOfType(entry_type)):
       
   382                                     raise ValueError, message
       
   383                                 else:
       
   384                                     self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
       
   385                             
       
   386                             if (entry_infos["dir"] == "I" and pdo_type != "Inputs" or 
       
   387                                 entry_infos["dir"] == "Q" and pdo_type != "Outputs"):
       
   388                                 raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
       
   389                             
       
   390                             ConfigureVariable(entry_infos, str_completion)
       
   391                         
       
   392                         elif pdo_type == "Outputs" and entry.getDataType() is not None and device_coe is not None:
       
   393                             data_type = entry.getDataType().getcontent()
       
   394                             entry_infos["dir"] = "Q"
       
   395                             entry_infos["data_size"] = max(1, entry_infos["bitlen"] / 8)
       
   396                             entry_infos["data_type"] = DATATYPECONVERSION.get(data_type)
       
   397                             entry_infos["var_type"] = data_type
       
   398                             entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos
       
   399                             
       
   400                             ConfigureVariable(entry_infos, str_completion)
       
   401                             
       
   402                             str_completion["slaves_output_pdos_default_values_extraction"] += \
       
   403                                 SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos
       
   404                             
       
   405                     if pdo_needed:
       
   406                         for excluded in pdo.getExclude():
       
   407                             excluded_index = ExtractHexDecValue(excluded.getcontent())
       
   408                             if excluded_index not in excluded_pdos:
       
   409                                 excluded_pdos.append(excluded_index)
       
   410                         
       
   411                         sm = pdo.getSm()
       
   412                         if sm is None:
       
   413                             for sm_idx, sync_manager in enumerate(sync_managers):
       
   414                                 if sync_manager["name"] == pdo_type:
       
   415                                     sm = sm_idx
       
   416                         if sm is None:
       
   417                             raise ValueError, _("No sync manager available for %s pdo!") % pdo_type
       
   418                             
       
   419                         sync_managers[sm]["pdos_number"] += 1
       
   420                         sync_managers[sm]["pdos"].append(
       
   421                             {"slave": slave_idx,
       
   422                              "index": pdo_index,
       
   423                              "name": ExtractName(pdo.getName()),
       
   424                              "type": pdo_type, 
       
   425                              "entries": entries_infos,
       
   426                              "entries_number": len(entries_infos),
       
   427                              "fixed": pdo.getFixed() == True})
       
   428             
       
   429                 if PdoConfig and PdoAssign:
       
   430                     dynamic_pdos = {}
       
   431                     dynamic_pdos_number = 0
       
   432                     for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), 
       
   433                                                            ("Outputs", 0x1a00, 0x1C00)]:
       
   434                         for sync_manager in sync_managers:
       
   435                             if sync_manager["name"] == category:
       
   436                                 category_infos = dynamic_pdos.setdefault(category, {})
       
   437                                 category_infos["sync_manager"] = sync_manager
       
   438                                 category_infos["pdos"] = [pdo for pdo in category_infos["sync_manager"]["pdos"] 
       
   439                                                           if not pdo["fixed"] and pdo["type"] == category]
       
   440                                 category_infos["current_index"] = min_index
       
   441                                 category_infos["max_index"] = max_index
       
   442                                 break
       
   443                     
       
   444                     for (index, subindex), entry_declaration in slave_variables.iteritems():
       
   445                         
       
   446                         if not entry_declaration["mapped"]:
       
   447                             entry = device_entries.get((index, subindex), None)
       
   448                             if entry is None:
       
   449                                 raise ValueError, _("Unknown entry index 0x%4.4x, subindex 0x%2.2x for device %s") % \
       
   450                                                  (index, subindex, type_infos["device_type"])
       
   451                             
   359                             entry_infos = {
   452                             entry_infos = {
   360                                 "index": index,
   453                                 "index": index,
   361                                 "subindex": subindex,
   454                                 "subindex": subindex,
   362                                 "name": ExtractName(entry.getName()),
   455                                 "name": entry["Name"],
   363                                 "bitlen": entry.getBitLen(),
   456                                 "bitlen": entry["BitSize"],
   364                             }
   457                             }
   365                             entry_infos.update(type_infos)
   458                             entry_infos.update(type_infos)
   366                             entries_infos.append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
   459                             
   367                             
   460                             entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"], 
   368                             entry_declaration = slave_variables.get((index, subindex), None)
   461                                                         entry_declaration["infos"])))
   369                             if entry_declaration is not None and not entry_declaration["mapped"]:
   462                             entry_declaration["mapped"] = True
   370                                 pdo_needed = True
   463                             
       
   464                             if entry_infos["var_type"] != entry["Type"]:
       
   465                                 message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
       
   466                                 if (self.Controler.GetSizeOfType(entry_infos["var_type"]) != 
       
   467                                     self.Controler.GetSizeOfType(entry["Type"])):
       
   468                                     raise ValueError, message
       
   469                                 else:
       
   470                                     self.Controler.GetCTRoot().logger.write_warning(message + "\n")
       
   471                             
       
   472                             if entry_infos["dir"] == "I" and entry["PDOMapping"] in ["T", "RT"]:
       
   473                                 pdo_type = "Inputs"
       
   474                             elif entry_infos["dir"] == "Q" and entry["PDOMapping"] in ["R", "RT"]:
       
   475                                 pdo_type = "Outputs"
       
   476                             else:
       
   477                                 raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
       
   478                             
       
   479                             if not dynamic_pdos.has_key(pdo_type):
       
   480                                 raise ValueError, _("No Sync manager defined for %s!") % pdo_type
       
   481                             
       
   482                             ConfigureVariable(entry_infos, str_completion)
       
   483                             
       
   484                             if len(dynamic_pdos[pdo_type]["pdos"]) > 0:
       
   485                                 pdo = dynamic_pdos[pdo_type]["pdos"][0]
       
   486                             elif module_extra_params["add_pdo"]:
       
   487                                 while dynamic_pdos[pdo_type]["current_index"] in pdos_index:
       
   488                                     dynamic_pdos[pdo_type]["current_index"] += 1
       
   489                                 if dynamic_pdos[pdo_type]["current_index"] >= dynamic_pdos[pdo_type]["max_index"]:
       
   490                                     raise ValueError, _("No more free PDO index available for %s!") % pdo_type
       
   491                                 pdos_index.append(dynamic_pdos[pdo_type]["current_index"])
   371                                 
   492                                 
   372                                 entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"], 
   493                                 dynamic_pdos_number += 1
   373                                                             entry_declaration["infos"])))
   494                                 pdo = {"slave": slave_idx,
   374                                 entry_declaration["mapped"] = True
   495                                        "index": dynamic_pdos[pdo_type]["current_index"],
   375                                 
   496                                        "name": "Dynamic PDO %d" % dynamic_pdos_number,
   376                                 entry_type = entry.getDataType().getcontent()
   497                                        "type": pdo_type, 
   377                                 if entry_infos["var_type"] != entry_type:
   498                                        "entries": [],
   378                                     message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
   499                                        "entries_number": 0,
   379                                     if (self.Controler.GetSizeOfType(entry_infos["var_type"]) != 
   500                                        "fixed": False}
   380                                         self.Controler.GetSizeOfType(entry_type)):
   501                                 dynamic_pdos[pdo_type]["sync_manager"]["pdos_number"] += 1
   381                                         raise ValueError, message
   502                                 dynamic_pdos[pdo_type]["sync_manager"]["pdos"].append(pdo)
   382                                     else:
   503                                 dynamic_pdos[pdo_type]["pdos"].append(pdo)
   383                                         self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
   504                             else:
   384                                 
   505                                 break
   385                                 if (entry_infos["dir"] == "I" and pdo_type != "Inputs" or 
   506                             
   386                                     entry_infos["dir"] == "Q" and pdo_type != "Outputs"):
   507                             pdo["entries"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
   387                                     raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
   508                             if entry_infos["bitlen"] < module_extra_params["pdo_alignment"]:
   388                                 
   509                                 pdo["entries"].append("    {0x0000, 0x00, %d}, /* None */" % (
   389                                 ConfigureVariable(entry_infos, str_completion)
   510                                         module_extra_params["pdo_alignment"] - entry_infos["bitlen"]))
   390                             
   511                             pdo["entries_number"] += 1
   391                             elif pdo_type == "Outputs" and entry.getDataType() is not None and device_coe is not None:
   512                             
   392                                 data_type = entry.getDataType().getcontent()
   513                             if pdo["entries_number"] == module_extra_params["max_pdo_size"]:
   393                                 entry_infos["dir"] = "Q"
   514                                 dynamic_pdos[pdo_type]["pdos"].pop(0)
   394                                 entry_infos["data_size"] = max(1, entry_infos["bitlen"] / 8)
   515                 
   395                                 entry_infos["data_type"] = DATATYPECONVERSION.get(data_type)
   516                 pdo_offset = 0
   396                                 entry_infos["var_type"] = data_type
   517                 entry_offset = 0
   397                                 entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos
   518                 for sync_manager_infos in sync_managers:
   398                                 
   519                 
   399                                 ConfigureVariable(entry_infos, str_completion)
   520                     for pdo_infos in sync_manager_infos["pdos"]:
   400                                 
   521                         pdo_infos["offset"] = entry_offset
   401                                 str_completion["slaves_output_pdos_default_values_extraction"] += \
   522                         pdo_entries = pdo_infos["entries"]
   402                                     SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos
   523                         pdos_infos["pdos_infos"].append(
   403                                 
   524                             ("    {0x%(index).4x, %(entries_number)d, " + 
   404                         if pdo_needed:
   525                              "slave_%(slave)d_pdo_entries + %(offset)d}, /* %(name)s */") % pdo_infos)
   405                             for excluded in pdo.getExclude():
   526                         entry_offset += len(pdo_entries)
   406                                 excluded_index = ExtractHexDecValue(excluded.getcontent())
   527                         pdos_infos["pdos_entries_infos"].extend(pdo_entries)
   407                                 if excluded_index not in excluded_pdos:
   528                     
   408                                     excluded_pdos.append(excluded_index)
   529                     sync_manager_infos["offset"] = pdo_offset
   409                             
   530                     pdo_offset_shift = sync_manager_infos["pdos_number"]
   410                             sm = pdo.getSm()
   531                     pdos_infos["pdos_sync_infos"].append(
   411                             if sm is None:
   532                         ("    {%(index)d, %(sync_manager_type)s, %(pdos_number)d, " + 
   412                                 for sm_idx, sync_manager in enumerate(sync_managers):
   533                          ("slave_%(slave)d_pdos + %(offset)d" if pdo_offset_shift else "NULL") +
   413                                     if sync_manager["name"] == pdo_type:
   534                          ", %(watchdog)s},") % sync_manager_infos)
   414                                         sm = sm_idx
   535                     pdo_offset += pdo_offset_shift  
   415                             if sm is None:
   536                 
   416                                 raise ValueError, _("No sync manager available for %s pdo!") % pdo_type
   537                 for element in ["pdos_entries_infos", "pdos_infos", "pdos_sync_infos"]:
   417                                 
   538                     pdos_infos[element] = "\n".join(pdos_infos[element])
   418                             sync_managers[sm]["pdos_number"] += 1
   539                 
   419                             sync_managers[sm]["pdos"].append(
   540                 str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos
   420                                 {"slave": slave_idx,
   541             
   421                                  "index": pdo_index,
   542             for (index, subindex), entry_declaration in slave_variables.iteritems():
   422                                  "name": ExtractName(pdo.getName()),
   543                 if not entry_declaration["mapped"]:
   423                                  "type": pdo_type, 
   544                     message = _("Entry index 0x%4.4x, subindex 0x%2.2x not mapped for device %s") % \
   424                                  "entries": entries_infos,
   545                                     (index, subindex, type_infos["device_type"])
   425                                  "entries_number": len(entries_infos),
   546                     self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
   426                                  "fixed": pdo.getFixed() == True})
       
   427                 
       
   428                     if PdoConfig and PdoAssign:
       
   429                         dynamic_pdos = {}
       
   430                         dynamic_pdos_number = 0
       
   431                         for category, min_index, max_index in [("Inputs", 0x1600, 0x1800), 
       
   432                                                                ("Outputs", 0x1a00, 0x1C00)]:
       
   433                             for sync_manager in sync_managers:
       
   434                                 if sync_manager["name"] == category:
       
   435                                     category_infos = dynamic_pdos.setdefault(category, {})
       
   436                                     category_infos["sync_manager"] = sync_manager
       
   437                                     category_infos["pdos"] = [pdo for pdo in category_infos["sync_manager"]["pdos"] 
       
   438                                                               if not pdo["fixed"] and pdo["type"] == category]
       
   439                                     category_infos["current_index"] = min_index
       
   440                                     category_infos["max_index"] = max_index
       
   441                                     break
       
   442                         
       
   443                         for (index, subindex), entry_declaration in slave_variables.iteritems():
       
   444                             
       
   445                             if not entry_declaration["mapped"]:
       
   446                                 entry = device_entries.get((index, subindex), None)
       
   447                                 if entry is None:
       
   448                                     raise ValueError, _("Unknown entry index 0x%4.4x, subindex 0x%2.2x for device %s") % \
       
   449                                                      (index, subindex, type_infos["device_type"])
       
   450                                 
       
   451                                 entry_infos = {
       
   452                                     "index": index,
       
   453                                     "subindex": subindex,
       
   454                                     "name": entry["Name"],
       
   455                                     "bitlen": entry["BitSize"],
       
   456                                 }
       
   457                                 entry_infos.update(type_infos)
       
   458                                 
       
   459                                 entry_infos.update(dict(zip(["var_type", "dir", "var_name", "no_decl", "extra_declarations"], 
       
   460                                                             entry_declaration["infos"])))
       
   461                                 entry_declaration["mapped"] = True
       
   462                                 
       
   463                                 if entry_infos["var_type"] != entry["Type"]:
       
   464                                     message = _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
       
   465                                     if (self.Controler.GetSizeOfType(entry_infos["var_type"]) != 
       
   466                                         self.Controler.GetSizeOfType(entry["Type"])):
       
   467                                         raise ValueError, message
       
   468                                     else:
       
   469                                         self.Controler.GetCTRoot().logger.write_warning(message + "\n")
       
   470                                 
       
   471                                 if entry_infos["dir"] == "I" and entry["PDOMapping"] in ["T", "RT"]:
       
   472                                     pdo_type = "Inputs"
       
   473                                 elif entry_infos["dir"] == "Q" and entry["PDOMapping"] in ["R", "RT"]:
       
   474                                     pdo_type = "Outputs"
       
   475                                 else:
       
   476                                     raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
       
   477                                 
       
   478                                 if not dynamic_pdos.has_key(pdo_type):
       
   479                                     raise ValueError, _("No Sync manager defined for %s!") % pdo_type
       
   480                                 
       
   481                                 ConfigureVariable(entry_infos, str_completion)
       
   482                                 
       
   483                                 if len(dynamic_pdos[pdo_type]["pdos"]) > 0:
       
   484                                     pdo = dynamic_pdos[pdo_type]["pdos"][0]
       
   485                                 elif module_extra_params["add_pdo"]:
       
   486                                     while dynamic_pdos[pdo_type]["current_index"] in pdos_index:
       
   487                                         dynamic_pdos[pdo_type]["current_index"] += 1
       
   488                                     if dynamic_pdos[pdo_type]["current_index"] >= dynamic_pdos[pdo_type]["max_index"]:
       
   489                                         raise ValueError, _("No more free PDO index available for %s!") % pdo_type
       
   490                                     pdos_index.append(dynamic_pdos[pdo_type]["current_index"])
       
   491                                     
       
   492                                     dynamic_pdos_number += 1
       
   493                                     pdo = {"slave": slave_idx,
       
   494                                            "index": dynamic_pdos[pdo_type]["current_index"],
       
   495                                            "name": "Dynamic PDO %d" % dynamic_pdos_number,
       
   496                                            "type": pdo_type, 
       
   497                                            "entries": [],
       
   498                                            "entries_number": 0,
       
   499                                            "fixed": False}
       
   500                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos_number"] += 1
       
   501                                     dynamic_pdos[pdo_type]["sync_manager"]["pdos"].append(pdo)
       
   502                                     dynamic_pdos[pdo_type]["pdos"].append(pdo)
       
   503                                 else:
       
   504                                     break
       
   505                                 
       
   506                                 pdo["entries"].append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
       
   507                                 if entry_infos["bitlen"] < module_extra_params["pdo_alignment"]:
       
   508                                     pdo["entries"].append("    {0x0000, 0x00, %d}, /* None */" % (
       
   509                                             module_extra_params["pdo_alignment"] - entry_infos["bitlen"]))
       
   510                                 pdo["entries_number"] += 1
       
   511                                 
       
   512                                 if pdo["entries_number"] == module_extra_params["max_pdo_size"]:
       
   513                                     dynamic_pdos[pdo_type]["pdos"].pop(0)
       
   514                     
       
   515                     pdo_offset = 0
       
   516                     entry_offset = 0
       
   517                     for sync_manager_infos in sync_managers:
       
   518                     
       
   519                         for pdo_infos in sync_manager_infos["pdos"]:
       
   520                             pdo_infos["offset"] = entry_offset
       
   521                             pdo_entries = pdo_infos["entries"]
       
   522                             pdos_infos["pdos_infos"].append(
       
   523                                 ("    {0x%(index).4x, %(entries_number)d, " + 
       
   524                                  "slave_%(slave)d_pdo_entries + %(offset)d}, /* %(name)s */") % pdo_infos)
       
   525                             entry_offset += len(pdo_entries)
       
   526                             pdos_infos["pdos_entries_infos"].extend(pdo_entries)
       
   527                         
       
   528                         sync_manager_infos["offset"] = pdo_offset
       
   529                         pdo_offset_shift = sync_manager_infos["pdos_number"]
       
   530                         pdos_infos["pdos_sync_infos"].append(
       
   531                             ("    {%(index)d, %(sync_manager_type)s, %(pdos_number)d, " + 
       
   532                              ("slave_%(slave)d_pdos + %(offset)d" if pdo_offset_shift else "NULL") +
       
   533                              ", %(watchdog)s},") % sync_manager_infos)
       
   534                         pdo_offset += pdo_offset_shift  
       
   535                     
       
   536                     for element in ["pdos_entries_infos", "pdos_infos", "pdos_sync_infos"]:
       
   537                         pdos_infos[element] = "\n".join(pdos_infos[element])
       
   538                     
       
   539                     str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos
       
   540                 
       
   541                 for (index, subindex), entry_declaration in slave_variables.iteritems():
       
   542                     if not entry_declaration["mapped"]:
       
   543                         message = _("Entry index 0x%4.4x, subindex 0x%2.2x not mapped for device %s") % \
       
   544                                         (index, subindex, type_infos["device_type"])
       
   545                         self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
       
   546                     
   547                     
   547         for element in ["used_pdo_entry_offset_variables_declaration", 
   548         for element in ["used_pdo_entry_offset_variables_declaration", 
   548                         "used_pdo_entry_configuration", 
   549                         "used_pdo_entry_configuration", 
   549                         "located_variables_declaration", 
   550                         "located_variables_declaration", 
   550                         "retrieve_variables", 
   551                         "retrieve_variables",