--- a/etherlab/ConfigEditor.py Tue Jan 10 15:11:22 2012 +0100
+++ b/etherlab/ConfigEditor.py Tue Jan 17 17:24:53 2012 +0100
@@ -96,23 +96,22 @@
else:
self.EndModal(wx.ID_OK)
+def GetSyncManagersTableColnames():
+ _ = lambda x : x
+ return ["#", _("Name"), _("Start Address"), _("Default Size"), _("Control Byte"), _("Enable")]
+
+class SyncManagersTable(CustomTable):
+
+ def GetValue(self, row, col):
+ if row < self.GetNumberRows():
+ if col == 0:
+ return row
+ return self.data[row].get(self.GetColLabelValue(col, False), "")
def GetVariablesTableColnames():
_ = lambda x : x
return ["#", _("Index"), _("SubIndex"), _("Name"), _("Type"), _("PDO index"), _("PDO name"), _("PDO type")]
-class PDOsTable(CustomTable):
-
- def GetValue(self, row, col):
- if row < self.GetNumberRows():
- if col == 0:
- return row + 1
- colname = self.GetColLabelValue(col, False)
- value = self.data[row].get(colname, "")
- if colname == "Type":
- value = _(value)
- return value
-
class VariablesTable(CustomTable):
def GetValue(self, row, col):
@@ -121,6 +120,31 @@
return row + 1
return self.data[row].get(self.GetColLabelValue(col, False), "")
+ def _updateColAttrs(self, grid):
+ """
+ wx.grid.Grid -> update the column attributes to add the
+ appropriate renderer given the column name.
+
+ Otherwise default to the default renderer.
+ """
+ for row in range(self.GetNumberRows()):
+ row_highlights = self.Highlights.get(row, {})
+ access = self.GetValueByName(row, "Access")
+ for col in range(self.GetNumberCols()):
+ colname = self.GetColLabelValue(col, False)
+
+ if colname in ["PDO index", "PDO name", "PDO type"] and access == "":
+ highlight_colours = (wx.LIGHT_GREY, wx.WHITE)
+ else:
+ highlight_colours = row_highlights.get(colname.lower(), [(wx.WHITE, wx.BLACK)])[-1]
+ grid.SetReadOnly(row, col, True)
+ grid.SetCellEditor(row, col, None)
+ grid.SetCellRenderer(row, col, None)
+
+ grid.SetCellBackgroundColour(row, col, highlight_colours[0])
+ grid.SetCellTextColour(row, col, highlight_colours[1])
+ self.ResizeRow(grid, row)
+
[ID_SLAVEPANEL, ID_SLAVEPANELTYPELABEL,
ID_SLAVEPANELTYPE, ID_SLAVEPANELTYPEBROWSE,
ID_SLAVEPANELALIASLABEL, ID_SLAVEPANELALIAS,
@@ -129,8 +153,8 @@
ID_SLAVEPANELVENDOR, ID_SLAVEPANELPRODUCTCODELABEL,
ID_SLAVEPANELPRODUCTCODE, ID_SLAVEPANELREVISIONNUMBERLABEL,
ID_SLAVEPANELREVISIONNUMBER, ID_SLAVEPANELPHYSICSLABEL,
- ID_SLAVEPANELPHYSICS, ID_SLAVEPANELPDOSLABEL,
- ID_SLAVEPANELPDOSGRID, ID_SLAVEPANELVARIABLESLABEL,
+ ID_SLAVEPANELPHYSICS, ID_SLAVEPANELSYNCMANAGERSLABEL,
+ ID_SLAVEPANELSYNCMANAGERSGRID, ID_SLAVEPANELVARIABLESLABEL,
ID_SLAVEPANELVARIABLESGRID,
] = [wx.NewId() for _init_ctrls in range(21)]
@@ -174,12 +198,15 @@
def _init_coll_SlaveInfosSizer_Items(self, parent):
parent.AddSizer(self.SlaveInfosDetailsSizer, 0, border=0, flag=wx.GROW)
+ parent.AddWindow(self.SyncManagersLabel, 0, border=0, flag=wx.GROW)
+ parent.AddWindow(self.SyncManagersGrid, 0, border=0, flag=wx.GROW)
parent.AddWindow(self.VariablesLabel, 0, border=0, flag=wx.GROW)
parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wx.GROW)
def _init_coll_SlaveInfosSizer_Growables(self, parent):
parent.AddGrowableCol(0)
- parent.AddGrowableRow(2)
+ parent.AddGrowableRow(2, 1)
+ parent.AddGrowableRow(4, 2)
def _init_coll_SlaveInfosDetailsSizer_Items(self, parent):
parent.AddWindow(self.VendorLabel, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.GROW)
@@ -200,7 +227,7 @@
self.PositionSizer = wx.FlexGridSizer(cols=6, hgap=5, rows=1, vgap=0)
self.TypeSizer = wx.BoxSizer(wx.HORIZONTAL)
self.SlaveInfosBoxSizer = wx.StaticBoxSizer(self.SlaveInfosStaticBox, wx.VERTICAL)
- self.SlaveInfosSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
+ self.SlaveInfosSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5)
self.SlaveInfosDetailsSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=2, vgap=5)
self._init_coll_MainSizer_Growables(self.MainSizer)
@@ -287,12 +314,20 @@
name='Physics', parent=self, pos=wx.Point(0, 0),
size=wx.Size(0, 24), style=wx.TE_READONLY)
+ self.SyncManagersLabel = wx.StaticText(id=ID_SLAVEPANELSYNCMANAGERSLABEL,
+ label=_('Sync managers:'), name='SyncManagersLabel', parent=self,
+ pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
+
+ self.SyncManagersGrid = CustomGrid(id=ID_SLAVEPANELSYNCMANAGERSGRID,
+ name='SyncManagersGrid', parent=self, pos=wx.Point(0, 0),
+ size=wx.Size(0, 0), style=wx.VSCROLL)
+
self.VariablesLabel = wx.StaticText(id=ID_SLAVEPANELVARIABLESLABEL,
label=_('Variable entries:'), name='VariablesLabel', parent=self,
pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
- self.VariablesGrid = CustomGrid(id=ID_SLAVEPANELPDOSGRID,
- name='PDOsGrid', parent=self, pos=wx.Point(0, 0),
+ self.VariablesGrid = CustomGrid(id=ID_SLAVEPANELVARIABLESGRID,
+ name='VariablesGrid', parent=self, pos=wx.Point(0, 0),
size=wx.Size(0, 0), style=wx.VSCROLL)
if wx.VERSION >= (2, 5, 0):
self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick)
@@ -308,6 +343,19 @@
self.ParentWindow = window
self.Slave = slave
+ self.SyncManagersTable = SyncManagersTable(self, [], GetSyncManagersTableColnames())
+ self.SyncManagersGrid.SetTable(self.SyncManagersTable)
+ self.SyncManagersGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_LEFT, wx.ALIGN_RIGHT,
+ wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT]
+ self.SyncManagersGridColSizes = [40, 150, 100, 100, 100, 100]
+ self.SyncManagersGrid.SetRowLabelSize(0)
+ for col in range(self.SyncManagersTable.GetNumberCols()):
+ attr = wx.grid.GridCellAttr()
+ attr.SetAlignment(self.SyncManagersGridColAlignements[col], wx.ALIGN_CENTRE)
+ self.SyncManagersGrid.SetColAttr(col, attr)
+ self.SyncManagersGrid.SetColMinimalWidth(col, self.SyncManagersGridColSizes[col])
+ self.SyncManagersGrid.AutoSizeColumn(col, False)
+
self.VariablesTable = VariablesTable(self, [], GetVariablesTableColnames())
self.VariablesGrid.SetTable(self.VariablesTable)
self.VariablesGridColAlignements = [wx.ALIGN_RIGHT, wx.ALIGN_RIGHT, wx.ALIGN_RIGHT,
@@ -346,7 +394,9 @@
self.ProductCode.SetValue(slave_infos["product_code"])
self.RevisionNumber.SetValue(slave_infos["revision_number"])
self.Physics.SetValue(slave_infos["physics"])
- self.VariablesTable.SetData(slave_infos["variables"])
+ self.SyncManagersTable.SetData(slave_infos["sync_managers"])
+ self.SyncManagersTable.ResetView(self.SyncManagersGrid)
+ self.VariablesTable.SetData(slave_infos["entries"])
self.VariablesTable.ResetView(self.VariablesGrid)
else:
type_infos = self.Controler.GetSlaveType(self.Slave)
@@ -394,22 +444,28 @@
event.Skip()
def OnVariablesGridCellLeftClick(self, event):
- if event.GetCol() == 0:
- row = event.GetRow()
- data_type = self.VariablesTable.GetValueByName(row, "Type")
- var_name = self.VariablesTable.GetValueByName(row, "Name")
+ row = event.GetRow()
+
+ data_type = self.VariablesTable.GetValueByName(row, "Type")
+ access = self.VariablesTable.GetValueByName(row, "Access")
+ if (event.GetCol() == 0 and access != "" and
+ self.Controler.GetSizeOfType(data_type) is not None):
+
entry_index = self.Controler.ExtractHexDecValue(self.VariablesTable.GetValueByName(row, "Index"))
- entry_subindex = self.VariablesTable.GetValueByName(row, "SubIndex")
- if self.VariablesTable.GetValueByName(row, "PDO type") == "Transmit":
+ entry_subindex = self.Controler.ExtractHexDecValue(self.VariablesTable.GetValueByName(row, "SubIndex"))
+ var_name = "%s_%4.4x_%2.2x" % (self.Type.GetValue(), entry_index, entry_subindex)
+ if access in ["ro"]:
dir = "%I"
else:
dir = "%Q"
location = "%s%s" % (dir, self.Controler.GetSizeOfType(data_type)) + \
".".join(map(lambda x:str(x), self.Controler.GetCurrentLocation() + self.Slave + (entry_index, entry_subindex)))
+
data = wx.TextDataObject(str((location, "location", data_type, var_name, "")))
dragSource = wx.DropSource(self.VariablesGrid)
dragSource.SetData(data)
dragSource.DoDragDrop()
+
event.Skip()
[ID_CONFIGEDITOR, ID_CONFIGEDITORADDSLAVEBUTTON,
--- a/etherlab/etherlab.py Tue Jan 10 15:11:22 2012 +0100
+++ b/etherlab/etherlab.py Tue Jan 17 17:24:53 2012 +0100
@@ -16,6 +16,8 @@
"USINT" : "U8", "UINT" : "U16", "UDINT" : "U32", "ULINT" : "U64",
"BYTE" : "U8", "WORD" : "U16", "DWORD" : "U32", "LWORD" : "U64"}
+VARCLASSCONVERSION = {"ro": LOCATION_VAR_INPUT, "wo": LOCATION_VAR_OUTPUT, "rw": LOCATION_VAR_MEMORY}
+
#--------------------------------------------------
# Ethercat MASTER
#--------------------------------------------------
@@ -30,7 +32,7 @@
try:
return int(value.replace("#", "0"), 16)
except:
- raise "Invalid value for HexDecValue \"%s\"" % value
+ raise ValueError, "Invalid value for HexDecValue \"%s\"" % value
def GenerateHexDecValue(value, base=10):
if base == 10:
@@ -38,7 +40,7 @@
elif base == 16:
return "#x%.8x" % value
else:
- raise "Not supported base"
+ raise ValueError, "Not supported base"
cls = EtherCATConfigClasses.get("Config_Slave", None)
if cls:
@@ -186,12 +188,12 @@
device = self.GetModuleInfos(type_infos)
if device is not None:
infos = type_infos.copy()
+ entries = device.GetEntriesList()
+ entries_list = entries.items()
+ entries_list.sort()
infos.update({"physics": device.getPhysics(),
- "variables": []})
- for TxPdo in device.getTxPdo():
- ExtractPdoInfos(TxPdo, "Transmit", infos)
- for RxPdo in device.getRxPdo():
- ExtractPdoInfos(RxPdo, "Receive", infos)
+ "sync_managers": device.GetSyncManagers(),
+ "entries": [entry[1] for entry in entries_list]})
return infos
return None
@@ -226,26 +228,22 @@
else:
sync_managers.append(LOCATION_VAR_INPUT)
- for pdo in device.getTxPdo() + device.getRxPdo():
- var_class = sync_managers[pdo.getSm()]
-
- for entry in pdo.getEntry():
- index = ExtractHexDecValue(entry.getIndex().getcontent())
- subindex = ExtractHexDecValue(entry.getSubIndex())
- var_type = entry.getDataType().getcontent()
- var_size = self.GetSizeOfType(var_type)
+ entries = device.GetEntriesList().items()
+ entries.sort()
+ for (index, subindex), entry in entries:
+ var_size = self.GetSizeOfType(entry["Type"])
+ if var_size is not None:
+ var_class = VARCLASSCONVERSION.get(entry["Access"], LOCATION_VAR_MEMORY)
if var_class == LOCATION_VAR_INPUT:
var_dir = "%I"
else:
var_dir = "%Q"
- pdo_name = ExtractName(pdo.getName())
- entry_name = ExtractName(entry.getName())
- vars.append({"name": "%s - %s" % (pdo_name, entry_name),
+ vars.append({"name": "0x%4.4x-0x%2.2x: %s" % (index, subindex, entry["Name"]),
"type": var_class,
"size": var_size,
- "IEC_type": var_type,
- "var_name": "%s_%s" % (type_infos["device_type"], "_".join(pdo_name.split())),
+ "IEC_type": entry["Type"],
+ "var_name": "%s_%4.4x_%2.2x" % (type_infos["device_type"], index, subindex),
"location": "%s%s%s"%(var_dir, var_size, ".".join(map(str, current_location +
slave_pos +
(index, subindex)))),
@@ -383,6 +381,54 @@
}
"""
+def ConfigureVariable(entry_infos, str_completion):
+ data_type = DATATYPECONVERSION.get(entry_infos["var_type"], None)
+ if data_type is None:
+ raise ValueError, _("Type of location \"%s\" not yet supported!") % entry_infos["var_name"]
+
+ str_completion["located_variables_declaration"].extend(
+ ["IEC_%(var_type)s beremiz%(var_name)s;" % entry_infos,
+ "IEC_%(var_type)s *%(var_name)s = &beremiz%(var_name)s;" % entry_infos])
+
+ if data_type == "BIT":
+ str_completion["used_pdo_entry_offset_variables_declaration"].extend(
+ ["static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos,
+ "static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x_bit;" % entry_infos])
+
+ str_completion["used_pdo_entry_configuration"].append(
+ (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, " +
+ "0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x, " +
+ "&slave%(slave)d_%(index).4x_%(subindex).2x_bit},") % entry_infos)
+
+ if entry_infos["dir"] == "I":
+ str_completion["retrieve_variables"].append(
+ (" beremiz%(name)s = EC_READ_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
+ "slave%(slave)d_%(index).4x_%(subindex).2x_bit);") % entry_infos)
+ elif entry_infos["dir"] == "Q":
+ str_completion["publish_variables"].append(
+ (" EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
+ "slave%(slave)d_%(index).4x_%(subindex).2x_bit, beremiz%(var_name)s);") % entry_infos)
+
+ else:
+ entry_infos["data_type"] = data_type
+
+ str_completion["used_pdo_entry_offset_variables_declaration"].append(
+ "static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos)
+
+ str_completion["used_pdo_entry_configuration"].append(
+ (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, " +
+ "%(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x},") % entry_infos)
+
+ if entry_infos["dir"] == "I":
+ str_completion["retrieve_variables"].append(
+ (" beremiz%(var_name)s = EC_READ_BIT(domain1_pd + " +
+ "slave%(slave)d_%(index).4x_%(subindex).2x);") % entry_infos)
+ elif entry_infos["dir"] == "Q":
+ str_completion["publish_variables"].append(
+ (" EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
+ "beremiz%(var_name)s);") % entry_infos)
+
+
class _EthercatCFileGenerator:
def __init__(self, controler, filepath):
@@ -399,10 +445,12 @@
entry_infos = slave_variables.get((index, subindex), None)
if entry_infos is None:
- slave_variables[(index, subindex)] = (iec_type, dir, name)
- elif entry_infos != (iec_type, dir, name):
+ slave_variables[(index, subindex)] = {
+ "infos": (iec_type, dir, name),
+ "mapped": False}
+ elif entry_infos["infos"] != (iec_type, dir, name):
raise ValueError, _("Definition conflict for location \"%s\"") % name
-
+
def GenerateCFile(self):
current_location = self.Controler.GetCurrentLocation()
@@ -428,6 +476,10 @@
"publish_variables": [],
}
+ for slave_entries in self.UsedVariables.itervalues():
+ for entry_infos in slave_entries.itervalues():
+ entry_infos["mapped"] = False
+
for slave_idx, slave_pos in enumerate(self.Controler.GetSlaves()):
slave = self.Controler.GetSlave(slave_pos)
@@ -436,10 +488,10 @@
device = self.Controler.GetModuleInfos(type_infos)
if device is not None:
+ slave_variables = self.UsedVariables.get(slave_pos, {})
+ device_entries = device.GetEntriesList()
- pdos = device.getTxPdo() + device.getRxPdo()
- if len(pdos) > 0:
- slave_variables = self.UsedVariables.get(slave_pos, {})
+ if len(device.getTxPdo() + device.getRxPdo()) > 0 or len(slave_variables) > 0:
for element in ["vendor", "product_code", "revision_number"]:
type_infos[element] = ExtractHexDecValue(type_infos[element])
@@ -459,7 +511,9 @@
for sync_manager_idx, sync_manager in enumerate(device.getSm()):
sync_manager_infos = {
"index": sync_manager_idx,
+ "name": sync_manager.getcontent(),
"slave": slave_idx,
+ "pdos": [],
"pdos_number": 0,
}
@@ -477,11 +531,14 @@
sync_managers.append(sync_manager_infos)
- entry_offset = 0
- for pdo in pdos:
+ pdos_index = []
+ for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
+ [(pdo, "Outputs") for pdo in device.getRxPdo()]):
entries = pdo.getEntry()
pdo_needed = pdo.getMandatory()
+ pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
+ pdos_index.append(pdo_index)
entries_infos = []
for entry in entries:
@@ -499,79 +556,126 @@
entry_declaration = slave_variables.get((index, subindex), None)
if entry_declaration is not None:
pdo_needed = True
- entry_infos.update(dict(zip(["var_type", "dir", "var_name"], entry_declaration)))
+
+ entry_infos.update(dict(zip(["var_type", "dir", "var_name"], entry_declaration["infos"])))
+ entry_declaration["mapped"] = True
if entry_infos["var_type"] != entry.getDataType().getcontent():
raise ValueError, _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
- data_type = DATATYPECONVERSION.get(entry_infos["var_type"], None)
- if data_type is None:
- raise ValueError, _("Type of location \"%s\" not yet supported!") % entry_infos["var_name"]
-
- if (entry_infos["dir"] == "I" and sync_managers[pdo.getSm()]["sync_manager_type"] != "EC_DIR_INPUT" or
- entry_infos["dir"] == "Q" and sync_managers[pdo.getSm()]["sync_manager_type"] != "EC_DIR_OUTPUT"):
+ if (entry_infos["dir"] == "I" and pdo_type != "Inputs" or
+ entry_infos["dir"] == "Q" and pdo_type != "Outputs"):
raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
- str_completion["located_variables_declaration"].extend(
- ["IEC_%(var_type)s beremiz%(var_name)s;" % entry_infos,
- "IEC_%(var_type)s *%(var_name)s = &beremiz%(var_name)s;" % entry_infos])
-
- if data_type == "BIT":
- str_completion["used_pdo_entry_offset_variables_declaration"].extend(
- ["static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos,
- "static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x_bit;" % entry_infos])
-
- str_completion["used_pdo_entry_configuration"].append(
- (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, " +
- "0x%(index).4x, %(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x, " +
- "&slave%(slave)d_%(index).4x_%(subindex).2x_bit},") % entry_infos)
-
- if entry_infos["dir"] == "I":
- str_completion["retrieve_variables"].append(
- (" beremiz%(name)s = EC_READ_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
- "slave%(slave)d_%(index).4x_%(subindex).2x_bit);") % entry_infos)
- elif entry_infos["dir"] == "Q":
- str_completion["publish_variables"].append(
- (" EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
- "slave%(slave)d_%(index).4x_%(subindex).2x_bit, beremiz%(var_name)s);") % entry_infos)
-
- else:
- entry_infos["data_type"] = data_type
-
- str_completion["used_pdo_entry_offset_variables_declaration"].append(
- "static unsigned int slave%(slave)d_%(index).4x_%(subindex).2x;" % entry_infos)
-
- str_completion["used_pdo_entry_configuration"].append(
- (" {%(alias)d, %(position)d, 0x%(vendor).8x, 0x%(product_code).8x, 0x%(index).4x, " +
- "%(subindex)d, &slave%(slave)d_%(index).4x_%(subindex).2x},") % entry_infos)
-
- if entry_infos["dir"] == "I":
- str_completion["retrieve_variables"].append(
- (" beremiz%(name)s = EC_READ_BIT(domain1_pd + " +
- "slave%(slave)d_%(index).4x_%(subindex).2x);") % entry_infos)
- elif entry_infos["dir"] == "Q":
- str_completion["publish_variables"].append(
- (" EC_WRITE_BIT(domain1_pd + slave%(slave)d_%(index).4x_%(subindex).2x, " +
- "beremiz%(var_name)s);") % entry_infos)
+ ConfigureVariable(entry_infos, str_completion)
if pdo_needed:
- sync_managers[pdo.getSm()]["pdos_number"] += 1
- pdo_infos = {
- "slave": slave_idx,
- "index": ExtractHexDecValue(pdo.getIndex().getcontent()),
- "name": ExtractName(pdo.getName()),
- "offset": entry_offset,
- "entries_number": len(entries)
+ sm = pdo.getSm()
+ if sm is None:
+ for sm_idx, sync_manager in enumerate(sync_managers):
+ if sync_manager["Name"] == pdo_type:
+ sm = sm_idx
+ if sm is None:
+ raise ValueError, _("No sync manager available for %s pdo!") % pdo_type
+
+ sync_managers[sm]["pdos_number"] += 1
+ sync_managers[sm]["pdos"].append(
+ {"slave": slave_idx,
+ "index": pdo_index,
+ "name": ExtractName(pdo.getName()),
+ "type": pdo_type,
+ "entries": entries_infos,
+ "entries_number": len(entries_infos),
+ "fixed": pdo.getFixed() == True})
+
+ dynamic_pdos = {}
+ dynamic_pdos_number = 0
+ for category, min_index, max_index in [("Inputs", 0x1600, 0x1800),
+ ("Outputs", 0x1a00, 0x1C00)]:
+ for sync_manager in sync_managers:
+ if sync_manager["name"] == category:
+ category_infos = dynamic_pdos.setdefault(category, {})
+ category_infos["sync_manager"] = sync_manager
+ category_infos["pdos"] = [pdo for pdo in category_infos["sync_manager"]["pdos"]
+ if not pdo["fixed"] and pdo["type"] == category]
+ category_infos["current_index"] = min_index
+ category_infos["max_index"] = max_index
+ break
+
+ for (index, subindex), entry_declaration in slave_variables.iteritems():
+
+ if not entry_declaration["mapped"]:
+ entry = device_entries.get((index, subindex), None)
+ if entry is None:
+ raise ValueError, _("Unknown entry index 0x%4.4x, subindex 0x%2.2x for device %s") % \
+ (index, subindex, type_infos["device_type"])
+
+ entry_infos = {
+ "index": index,
+ "subindex": subindex,
+ "name": entry["Name"],
+ "bitlen": entry["BitSize"],
}
+ entry_infos.update(type_infos)
+
+ entry_infos.update(dict(zip(["var_type", "dir", "var_name"], entry_declaration["infos"])))
+ entry_declaration["mapped"] = True
+
+ if entry_infos["var_type"] != entry["Type"]:
+ raise ValueError, _("Wrong type for location \"%s\"!") % entry_infos["var_name"]
+
+ if entry_infos["dir"] == "I" and entry["Access"] in ["ro", "rw"]:
+ pdo_type = "Inputs"
+ elif entry_infos["dir"] == "Q" and entry["Access"] in ["wo", "rw"]:
+ pdo_type = "Outputs"
+ else:
+ raise ValueError, _("Wrong direction for location \"%s\"!") % entry_infos["var_name"]
+
+ if not dynamic_pdos.has_key(pdo_type):
+ raise ValueError, _("No Sync manager defined for %s!") % pdo_type
+
+ ConfigureVariable(entry_infos, str_completion)
+
+ if len(dynamic_pdos[pdo_type]["pdos"]) > 0:
+ pdo = dynamic_pdos[pdo_type]["pdos"][0]
+ else:
+ while dynamic_pdos[pdo_type]["current_index"] in pdos_index:
+ dynamic_pdos[pdo_type]["current_index"] += 1
+ if dynamic_pdos[pdo_type]["current_index"] >= dynamic_pdos[pdo_type]["max_index"]:
+ raise ValueError, _("No more free PDO index available for %s!") % pdo_type
+ pdos_index.append(dynamic_pdos[pdo_type]["current_index"])
+
+ dynamic_pdos_number += 1
+ pdo = {"slave": slave_idx,
+ "index": dynamic_pdos[pdo_type]["current_index"],
+ "name": "Dynamic PDO %d" % dynamic_pdos_number,
+ "type": pdo_type,
+ "entries": [],
+ "entries_number": 0,
+ "fixed": False}
+ dynamic_pdos[pdo_type]["sync_manager"]["pdos_number"] += 1
+ dynamic_pdos[pdo_type]["sync_manager"]["pdos"].append(pdo)
+ dynamic_pdos[pdo_type]["pdos"].append(pdo)
+
+ pdo["entries"].append(" {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
+ pdo["entries_number"] += 1
+
+ if pdo["entries_number"] == 255:
+ dynamic_pdos[pdo_type]["pdos"].pop(0)
+
+ pdo_offset = 0
+ entry_offset = 0
+ for sync_manager_infos in sync_managers:
+
+ for pdo_infos in sync_manager_infos["pdos"]:
+ pdo_infos["offset"] = entry_offset
+ pdo_entries = pdo_infos["entries"]
pdos_infos["pdos_infos"].append(
(" {0x%(index).4x, %(entries_number)d, " +
"slave_%(slave)d_pdo_entries + %(offset)d}, /* %(name)s */") % pdo_infos)
- entry_offset += len(entries)
- pdos_infos["pdos_entries_infos"].extend(entries_infos)
-
-
- pdo_offset = 0
- for sync_manager_infos in sync_managers:
+ entry_offset += len(pdo_entries)
+ pdos_infos["pdos_entries_infos"].extend(pdo_entries)
+
sync_manager_infos["offset"] = pdo_offset
pdos_infos["pdos_sync_infos"].append(
(" {%(index)d, %(sync_manager_type)s, %(pdos_number)d, " +
@@ -600,6 +704,126 @@
EtherCATInfoClasses = GenerateClassesFromXSD(os.path.join(os.path.dirname(__file__), "EtherCATInfo.xsd"))
+cls = EtherCATInfoClasses["EtherCATInfo.xsd"].get("DeviceType", None)
+if cls:
+ cls.DataTypes = None
+
+ def GetProfileDictionaries(self):
+ dictionaries = []
+
+ for profile in self.getProfile():
+
+ profile_content = profile.getcontent()
+ if profile_content is None:
+ return None
+
+ for content_element in profile_content["value"]:
+ if content_element["name"] == "Dictionary":
+ dictionaries.append(content_element["value"])
+ elif content_element["name"] == "DictionaryFile":
+ raise ValueError, "DictionaryFile for defining Device Profile is not yet supported!"
+
+ return dictionaries
+ setattr(cls, "GetProfileDictionaries", GetProfileDictionaries)
+
+ def ExtractDataTypes(self):
+ self.DataTypes = {}
+
+ for dictionary in self.GetProfileDictionaries():
+
+ datatypes = dictionary.getDataTypes()
+ if datatypes is not None:
+
+ for datatype in datatypes.getDataType():
+ content = datatype.getcontent()
+ if content is not None and content["name"] == "SubItem":
+ self.DataTypes[datatype.getName()] = datatype
+
+ setattr(cls, "ExtractDataTypes", ExtractDataTypes)
+
+ def GetEntriesList(self):
+ if self.DataTypes is None:
+ self.ExtractDataTypes()
+
+ entries = {}
+
+ for dictionary in self.GetProfileDictionaries():
+
+ for object in dictionary.getObjects().getObject():
+ entry_index = object.getIndex().getcontent()
+ index = ExtractHexDecValue(entry_index)
+ entry_type = object.getType()
+ entry_name = ExtractName(object.getName())
+
+ entry_type_infos = self.DataTypes.get(entry_type, None)
+ if entry_type_infos is not None:
+ content = entry_type_infos.getcontent()
+ for subitem in content["value"]:
+ entry_subidx = subitem.getSubIdx()
+ if entry_subidx is None:
+ entry_subidx = "0"
+ subidx = ExtractHexDecValue(entry_subidx)
+ subitem_access = ""
+ subitem_flags = subitem.getFlags()
+ if subitem_flags is not None:
+ access = subitem_flags.getAccess()
+ if access is not None:
+ subitem_access = access.getcontent()
+ entries[(index, subidx)] = {
+ "Index": entry_index,
+ "SubIndex": entry_subidx,
+ "Name": "%s - %s" %
+ (entry_name.decode("utf-8"),
+ ExtractName(subitem.getDisplayName(),
+ subitem.getName()).decode("utf-8")),
+ "Type": subitem.getType(),
+ "BitSize": subitem.getBitSize(),
+ "Access": subitem_access,
+ "PDO index": "",
+ "PDO name": "",
+ "PDO type": ""}
+ else:
+ entry_access = ""
+ entry_flags = object.getFlags()
+ if entry_flags is not None:
+ access = entry_flags.getAccess()
+ if access is not None:
+ entry_access = access.getcontent()
+ entries[(index, 0)] = {
+ "Index": entry_index,
+ "SubIndex": "0",
+ "Name": entry_name,
+ "Type": entry_type,
+ "BitSize": object.getBitSize(),
+ "Access": entry_access,
+ "PDO index": "",
+ "PDO name": "",
+ "PDO type": ""}
+
+ for TxPdo in self.getTxPdo():
+ ExtractPdoInfos(TxPdo, "Transmit", entries)
+ for RxPdo in self.getRxPdo():
+ ExtractPdoInfos(RxPdo, "Receive", entries)
+
+ return entries
+ setattr(cls, "GetEntriesList", GetEntriesList)
+
+ def GetSyncManagers(self):
+ sync_managers = []
+ for sync_manager in self.getSm():
+ sync_manager_infos = {}
+ for name, value in [("Name", sync_manager.getcontent()),
+ ("Start Address", sync_manager.getStartAddress()),
+ ("Default Size", sync_manager.getDefaultSize()),
+ ("Control Byte", sync_manager.getControlByte()),
+ ("Enable", sync_manager.getEnable())]:
+ if value is None:
+ value =""
+ sync_manager_infos[name] = value
+ sync_managers.append(sync_manager_infos)
+ return sync_managers
+ setattr(cls, "GetSyncManagers", GetSyncManagers)
+
def GroupItemCompare(x, y):
if x["type"] == y["type"]:
if x["type"] == ETHERCAT_GROUP:
@@ -625,16 +849,34 @@
return name.getcontent()
return default
-def ExtractPdoInfos(pdo, pdo_type, infos):
+def ExtractPdoInfos(pdo, pdo_type, entries):
pdo_index = pdo.getIndex().getcontent()
- for entry in pdo.getEntry():
- infos["variables"].append({"Index": entry.getIndex().getcontent(),
- "SubIndex": entry.getSubIndex(),
- "Name": ExtractName(entry.getName()),
- "Type": entry.getDataType().getcontent(),
- "PDO index": pdo_index,
- "PDO name": ExtractName(pdo.getName()),
- "PDO type": pdo_type})
+ pdo_name = ExtractName(pdo.getName())
+ for pdo_entry in pdo.getEntry():
+ entry_index = pdo_entry.getIndex().getcontent()
+ entry_subindex = pdo_entry.getSubIndex()
+ index = ExtractHexDecValue(entry_index)
+ subindex = ExtractHexDecValue(entry_subindex)
+
+ entry = entries.get((index, subindex), None)
+ if entry is not None:
+ entry["PDO index"] = pdo_index
+ entry["PDO name"] = pdo_name
+ entry["PDO type"] = pdo_type
+ else:
+ if pdo_type == "Transmit":
+ access = "ro"
+ else:
+ access = "wo"
+ entries[(index, subindex)] = {
+ "Index": entry_index,
+ "SubIndex": entry_subindex,
+ "Name": ExtractName(pdo_entry.getName()),
+ "Type": pdo_entry.getDataType().getcontent(),
+ "Access": access,
+ "PDO index": pdo_index,
+ "PDO name": pdo_name,
+ "PDO type": pdo_type}
class RootClass:
@@ -750,11 +992,11 @@
if vendor is not None:
for group_name, group in vendor["groups"].iteritems():
for device_type, device in group["devices"]:
- product_code = device.getType().getProductCode()
- revision_number = device.getType().getRevisionNo()
+ product_code = ExtractHexDecValue(device.getType().getProductCode())
+ revision_number = ExtractHexDecValue(device.getType().getRevisionNo())
if (device_type == type_infos["device_type"] and
- product_code == type_infos["product_code"] and
- revision_number == type_infos["revision_number"]):
+ product_code == ExtractHexDecValue(type_infos["product_code"]) and
+ revision_number == ExtractHexDecValue(type_infos["revision_number"])):
return device
return None