22 #License along with this library; if not, write to the Free Software |
22 #License along with this library; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 from types import * |
25 from types import * |
26 |
26 |
|
27 # Translation between IEC types and Can Open types |
27 DicoTypes = {"BOOL":0x01, "SINT":0x02, "INT":0x03,"DINT":0x04,"LINT":0x10, |
28 DicoTypes = {"BOOL":0x01, "SINT":0x02, "INT":0x03,"DINT":0x04,"LINT":0x10, |
28 "USINT":0x05,"UINT":0x06,"UDINT":0x07,"ULINT":0x1B,"REAL":0x08, |
29 "USINT":0x05,"UINT":0x06,"UDINT":0x07,"ULINT":0x1B,"REAL":0x08, |
29 "LREAL":0x11,"STRING":0x09,"BYTE":0x05,"WORD":0x06,"DWORD":0x07, |
30 "LREAL":0x11,"STRING":0x09,"BYTE":0x05,"WORD":0x06,"DWORD":0x07, |
30 "LWORD":0x1B,"WSTRING":0x0B} |
31 "LWORD":0x1B,"WSTRING":0x0B} |
31 |
32 |
32 DictLocations = {} |
33 DictNameVariable = { "" : 1, "X": 2, "B": 3, "W": 4, "D": 5, "L": 6, "increment": 0x100, 1:("__I", 0x2000), 2:("__Q", 0x4000)} |
33 DictCobID = {} |
|
34 DictLocationsNotMapped = {} |
|
35 ListCobIDAvailable = [] |
|
36 SlavesPdoNumber = {} |
|
37 |
34 |
38 # Constants for PDO types |
35 # Constants for PDO types |
39 RPDO = 1 |
36 RPDO = 1 |
40 TPDO = 2 |
37 TPDO = 2 |
41 SlavePDOType = {"I" : TPDO, "Q" : RPDO} |
38 SlavePDOType = {"I" : TPDO, "Q" : RPDO} |
42 InvertPDOType = {RPDO : TPDO, TPDO : RPDO} |
39 InvertPDOType = {RPDO : TPDO, TPDO : RPDO} |
43 |
40 |
44 DefaultTransmitTypeMaster = 0x01 |
|
45 |
|
46 GenerateMasterMapping = lambda x:[None] + [(loc_infos["type"], name) for name, loc_infos in x] |
41 GenerateMasterMapping = lambda x:[None] + [(loc_infos["type"], name) for name, loc_infos in x] |
47 |
42 |
48 TrashVariableSizes = {1 : 0x01, 8 : 0x05, 16 : 0x06, 32 : 0x07, 64 : 0x1B} |
43 TrashVariableSizes = {1 : 0x01, 8 : 0x05, 16 : 0x06, 32 : 0x07, 64 : 0x1B} |
49 |
44 |
50 |
45 def LE_to_BE(value, size): |
51 def GetSlavePDOIndexes(slave, type, parameters = False): |
46 """ |
|
47 Convert Little Endian to Big Endian |
|
48 @param value: value expressed in integer |
|
49 @param size: number of bytes generated |
|
50 @return: a string containing the value converted |
|
51 """ |
|
52 |
|
53 data = ("%" + str(size * 2) + "." + str(size * 2) + "X") % value |
|
54 list_car = [data[i:i+2] for i in xrange(0, len(data), 2)] |
|
55 list_car.reverse() |
|
56 return "".join([chr(int(car, 16)) for car in list_car]) |
|
57 |
|
58 def GetNodePDOIndexes(node, type, parameters = False): |
|
59 """ |
|
60 Find the PDO indexes of a node |
|
61 @param node: node |
|
62 @param type: type of PDO searched (RPDO or TPDO or both) |
|
63 @param parameters: indicate which indexes are expected (PDO paramaters : True or PDO mappings : False) |
|
64 @return: a list of indexes found |
|
65 """ |
|
66 |
52 indexes = [] |
67 indexes = [] |
53 if type & RPDO: |
68 if type & RPDO: |
54 indexes.extend([idx for idx in slave.GetIndexes() if 0x1400 <= idx <= 0x15FF]) |
69 indexes.extend([idx for idx in node.GetIndexes() if 0x1400 <= idx <= 0x15FF]) |
55 if type & TPDO: |
70 if type & TPDO: |
56 indexes.extend([idx for idx in slave.GetIndexes() if 0x1800 <= idx <= 0x19FF]) |
71 indexes.extend([idx for idx in node.GetIndexes() if 0x1800 <= idx <= 0x19FF]) |
57 if not parameters: |
72 if not parameters: |
58 return [idx + 0x200 for idx in indexes] |
73 return [idx + 0x200 for idx in indexes] |
59 else: |
74 else: |
60 return indexes |
75 return indexes |
61 |
76 |
62 |
77 def SearchNodePDOMapping(loc_infos, node): |
63 def LE_to_BE(value, size): # Convert Little Endian to Big Endian |
78 """ |
64 data = ("%" + str(size * 2) + "." + str(size * 2) + "X") % value |
79 Find the PDO indexes of a node |
65 list_car = [data[i:i+2] for i in xrange(0, len(data), 2)] |
80 @param node: node |
66 list_car.reverse() |
81 @param type: type of PDO searched (RPDO or TPDO or both) |
67 return "".join([chr(int(car, 16)) for car in list_car]) |
82 @param parameters: indicate which indexes are expected (PDO paramaters : True or PDO mappings : False) |
68 |
83 @return: a list of indexes found |
69 |
84 """ |
70 |
85 |
71 def SearchSlavePDOMapping(loc_infos, slave): # Search the TPDO or RPDO mapping where location is defined on the slave |
86 typeinfos = node.GetEntryInfos(loc_infos["type"]) |
72 typeinfos = slave.GetEntryInfos(loc_infos["type"]) |
|
73 model = (loc_infos["index"] << 16) + (loc_infos["subindex"] << 8) + typeinfos["size"] |
87 model = (loc_infos["index"] << 16) + (loc_infos["subindex"] << 8) + typeinfos["size"] |
74 slavePDOidxlist = GetSlavePDOIndexes(slave, loc_infos["pdotype"]) |
88 |
75 |
89 for PDOidx in GetNodePDOIndexes(node, loc_infos["pdotype"]): |
76 for PDOidx in slavePDOidxlist: |
90 values = node.GetEntry(PDOidx) |
77 values = slave.GetEntry(PDOidx) |
|
78 if values != None: |
91 if values != None: |
79 for subindex, mapping in enumerate(values): |
92 for subindex, mapping in enumerate(values): |
80 if subindex != 0 and mapping == model: |
93 if subindex != 0 and mapping == model: |
81 return PDOidx, subindex |
94 return PDOidx, subindex |
82 return None |
95 return None |
83 |
96 |
84 def GenerateMappingDCF(cobid, idx, pdomapping, mapped): # Build concise DCF |
97 class ConciseDCFGenerator: |
85 |
98 |
86 # Create entry for RPDO or TPDO parameters and Disable PDO |
99 def __init__(self, nodelist): |
87 dcfdata = LE_to_BE(idx, 2) + LE_to_BE(0x01, 1) + LE_to_BE(0x04, 4) + LE_to_BE((0x80000000 + cobid), 4) |
100 # Dictionary of location informations classed by name |
88 # Set Transmit type synchrone |
101 self.DictLocations = {} |
89 dcfdata += LE_to_BE(idx, 2) + LE_to_BE(0x02, 1) + LE_to_BE(0x01, 4) + LE_to_BE(DefaultTransmitTypeSlave, 1) |
102 # Dictionary of location informations classed by name |
90 # Re-Enable PDO |
103 self.DictCobID = {} |
91 # ---- INDEX ----- --- SUBINDEX ---- ----- SIZE ------ ------ DATA ------ |
104 # Dictionary of location that have not been mapped yet |
92 dcfdata += LE_to_BE(idx, 2) + LE_to_BE(0x01, 1) + LE_to_BE(0x04, 4) + LE_to_BE(0x00000000 + cobid, 4) |
105 self.DictLocationsNotMapped = {} |
93 nbparams = 3 |
106 # List of COB IDs available |
94 if mapped == False and pdomapping != None: |
107 self.ListCobIDAvailable = range(0x180, 0x580) |
95 # Map Variables |
108 self.SlavesPdoNumber = {} |
96 for subindex, (name, loc_infos) in enumerate(pdomapping): |
109 # Dictionary of mapping value where unexpected variables are stored |
97 value = (loc_infos["index"] << 16) + (loc_infos["subindex"] << 8) + loc_infos["size"] |
110 TrashVariableValue = {} |
98 dcfdata += LE_to_BE(idx + 0x200, 2) + LE_to_BE(subindex + 1, 1) + LE_to_BE(0x04, 4) + LE_to_BE(value, 4) |
111 |
99 nbparams += 1 |
112 self.NodeList = nodelist |
100 return dcfdata, nbparams |
113 self.Manager = self.NodeList.Manager |
101 |
114 self.MasterNode = self.Manager.GetCurrentNodeCopy() |
102 def GetNewCobID(nodeid, type): # Return a cobid not used |
115 self.PrepareMasterNode() |
103 global ListCobIDAvailable, SlavesPdoNumber |
116 |
104 |
117 def RemoveUsedNodeCobId(self, node): |
105 if len(ListCobIDAvailable) == 0: |
118 """ |
|
119 Remove all PDO COB ID used by the given node from the list of available COB ID |
|
120 @param node: node |
|
121 @return: a tuple of number of RPDO and TPDO for the node |
|
122 """ |
|
123 |
|
124 # Get list of all node TPDO and RPDO indexes |
|
125 nodeRpdoIndexes = GetNodePDOIndexes(node, RPDO, True) |
|
126 nodeTpdoIndexes = GetNodePDOIndexes(node, TPDO, True) |
|
127 |
|
128 # Mark all the COB ID of the node already mapped PDO as not available |
|
129 for PdoIdx in nodeRpdoIndexes + nodeTpdoIndexes: |
|
130 pdo_cobid = node.GetEntry(PdoIdx, 0x01) |
|
131 # Extract COB ID, if PDO isn't active |
|
132 if pdo_cobid > 0x600 : |
|
133 pdo_cobid -= 0x80000000 |
|
134 # Remove COB ID from the list of available COB ID |
|
135 if pdo_cobid in self.ListCobIDAvailable: |
|
136 self.ListCobIDAvailable.remove(pdo_cobid) |
|
137 |
|
138 return len(nodeRpdoIndexes), len(nodeTpdoIndexes) |
|
139 |
|
140 def PrepareMasterNode(self): |
|
141 """ |
|
142 Add mandatory entries for DCF generation into MasterNode. |
|
143 """ |
|
144 |
|
145 # Adding DCF entry into Master node |
|
146 if not self.MasterNode.IsEntry(0x1F22): |
|
147 self.MasterNode.AddEntry(0x1F22, 1, "") |
|
148 self.Manager.AddSubentriesToCurrent(0x1F22, 127, masternode) |
|
149 |
|
150 # Adding trash mappable variables for unused mapped datas |
|
151 idxTrashVariables = 0x2000 + masternode.GetNodeID() |
|
152 # Add an entry for storing unexpected all variable |
|
153 self.Manager.AddMapVariableToCurrent(idxTrashVariables, "trashvariables", 3, len(TrashVariableSizes), self.MasterNode) |
|
154 for subidx, (size, typeidx) in enumerate(TrashVariableSizes.items()): |
|
155 # Add a subentry for storing unexpected variable of this size |
|
156 self.Manager.SetCurrentEntry(idxTrashVariables, subidx + 1, "TRASH%d" % size, "name", None, self.MasterNode) |
|
157 self.Manager.SetCurrentEntry(idxTrashVariables, subidx + 1, typeidx, "type", None, self.MasterNode) |
|
158 # Store the mapping value for this entry |
|
159 self.TrashVariableValue[size] = (idxTrashVariables << 16) + ((subidx + 1) << 8) + size |
|
160 |
|
161 RPDOnumber, TPDOnumber = self.RemoveUsedNodeCobId(self.MasterNode) |
|
162 |
|
163 # Store the indexes of the first RPDO and TPDO available for MasterNode |
|
164 self.CurrentPDOParamsIdx = {RPDO : 0x1400 + RPDOnumber, TPDO : 0x1800 + TPDOnumber} |
|
165 |
|
166 # Prepare MasterNode with all nodelist slaves |
|
167 for nodeid, nodeinfos in self.NodeList.SlaveNodes.items(): |
|
168 node = nodeinfos["Node"] |
|
169 node.SetNodeID(nodeid) |
|
170 |
|
171 RPDOnumber, TPDOnumber = self.RemoveUsedNodeCobId(node) |
|
172 |
|
173 # Store the number of TPDO and RPDO for this node |
|
174 self.SlavesPdoNumber[nodeid] = {RPDO : RPDOnumber, TPDO : TPDOnumber} |
|
175 |
|
176 # Get Slave's default SDO server parameters |
|
177 RSDO_cobid = node.GetEntry(0x1200,0x01) |
|
178 if not RSDO_cobid: |
|
179 RSDO_cobid = 0x600 + nodeid |
|
180 TSDO_cobid = node.GetEntry(0x1200,0x02) |
|
181 if not TSDO_cobid: |
|
182 TSDO_cobid = 0x580 + nodeid |
|
183 |
|
184 # Configure Master's SDO parameters entries |
|
185 self.Manager.ManageEntriesOfCurrent([0x1280 + nodeid], [], self.MasterNode) |
|
186 self.MasterNode.SetEntry(0x1280 + nodeid, 0x01, RSDO_cobid) |
|
187 self.MasterNode.SetEntry(0x1280 + nodeid, 0x02, TSDO_cobid) |
|
188 self.MasterNode.SetEntry(0x1280 + nodeid, 0x03, nodeid) |
|
189 |
|
190 def GetMasterNode(self): |
|
191 """ |
|
192 Return MasterNode. |
|
193 """ |
|
194 return self.MasterNode |
|
195 |
|
196 # Build concise DCF |
|
197 def GenerateMappingDCF(cobid, idx, pdomapping, mapped): |
|
198 |
|
199 # Create entry for RPDO or TPDO parameters and Disable PDO |
|
200 dcfdata = LE_to_BE(idx, 2) + LE_to_BE(0x01, 1) + LE_to_BE(0x04, 4) + LE_to_BE((0x80000000 + cobid), 4) |
|
201 # Set Transmit type synchrone |
|
202 dcfdata += LE_to_BE(idx, 2) + LE_to_BE(0x02, 1) + LE_to_BE(0x01, 4) + LE_to_BE(DefaultTransmitTypeSlave, 1) |
|
203 # Re-Enable PDO |
|
204 # ---- INDEX ----- --- SUBINDEX ---- ----- SIZE ------ ------ DATA ------ |
|
205 dcfdata += LE_to_BE(idx, 2) + LE_to_BE(0x01, 1) + LE_to_BE(0x04, 4) + LE_to_BE(0x00000000 + cobid, 4) |
|
206 nbparams = 3 |
|
207 if mapped == False and pdomapping != None: |
|
208 # Map Variables |
|
209 for subindex, (name, loc_infos) in enumerate(pdomapping): |
|
210 value = (loc_infos["index"] << 16) + (loc_infos["subindex"] << 8) + loc_infos["size"] |
|
211 dcfdata += LE_to_BE(idx + 0x200, 2) + LE_to_BE(subindex + 1, 1) + LE_to_BE(0x04, 4) + LE_to_BE(value, 4) |
|
212 nbparams += 1 |
|
213 return dcfdata, nbparams |
|
214 |
|
215 # Return a cobid not used |
|
216 def GetNewCobID(self, nodeid, type): |
|
217 """ |
|
218 Select a COB ID from the list of those available |
|
219 @param nodeid: id of the slave node |
|
220 @param type: type of PDO (RPDO or TPDO) |
|
221 @return: a tuple of the COD ID and PDO index or None |
|
222 """ |
|
223 # Verify that there is still some cobid available |
|
224 if len(self.ListCobIDAvailable) == 0: |
|
225 return None |
|
226 |
|
227 # Get the number of PDO of the type given for the node |
|
228 nbSlavePDO = self.SlavesPdoNumber[nodeid][type] |
|
229 if type == RPDO: |
|
230 if nbSlavePDO < 4: |
|
231 # For the four first RPDO -> cobid = 0x200 + ( numPdo parameters * 0x100) + nodeid |
|
232 newcobid = (0x200 + nbSlavePDO * 0x100 + nodeid) |
|
233 # Return calculated cobid if it's still available |
|
234 if newcobid in self.ListCobIDAvailable: |
|
235 self.ListCobIDAvailable.remove(newcobid) |
|
236 return newcobid, 0x1400 + nbSlavePDO |
|
237 # Return the first cobid available if no cobid found |
|
238 return self.ListCobIDAvailable.pop(0), 0x1400 + nbSlavePDO |
|
239 |
|
240 elif type == TPDO: |
|
241 if nbSlavePDO < 4: |
|
242 # For the four first TPDO -> cobid = 0x180 + ( numPdo parameters * 0x100) + nodeid |
|
243 newcobid = (0x180 + nbSlavePDO * 0x100 + nodeid) |
|
244 # Return calculated cobid if it's still available |
|
245 if newcobid in self.ListCobIDAvailable: |
|
246 self.ListCobIDAvailable.remove(newcobid) |
|
247 return newcobid, 0x1800 + nbSlavePDO |
|
248 # Return the first cobid available if no cobid found |
|
249 return self.ListCobIDAvailable.pop(0), 0x1800 + nbSlavePDO |
|
250 |
106 return None |
251 return None |
107 |
252 |
108 nbSlavePDO = SlavesPdoNumber[nodeid][type] |
253 def GenerateDCF(self, locations, current_location, sync_TPDOs): |
109 if type == RPDO: |
254 """ |
110 if nbSlavePDO < 4: |
255 Generate Concise DCF of MasterNode for the locations list given |
111 # For the fourth PDO -> cobid = 0x200 + ( numPdo parameters * 0x100) + nodeid |
256 @param locations: list of locations to be mapped |
112 newcobid = (0x200 + nbSlavePDO * 0x100 + nodeid) |
257 @param current_location: tuple of the located prefixes not to be considered |
113 if newcobid in ListCobIDAvailable: |
258 @param sync_TPDOs: indicate if TPDO must be synchronous |
114 ListCobIDAvailable.remove(newcobid) |
259 """ |
115 return newcobid, 0x1400 + nbSlavePDO |
260 |
116 return ListCobIDAvailable.pop(0), 0x1400 + nbSlavePDO |
261 # Get list of locations check if exists and mappables -> put them in DictLocations |
117 |
262 for location in locations: |
118 elif type == TPDO: |
263 COlocationtype = DicoTypes[location["IEC_TYPE"]] |
119 if nbSlavePDO < 4: |
264 name = location["NAME"] |
120 # For the fourth PDO -> cobid = 0x180 + (numPdo parameters * 0x100) + nodeid |
265 if name in DictLocations: |
121 newcobid = (0x180 + nbSlavePDO * 0x100 + nodeid) |
266 if DictLocations[name]["type"] != COlocationtype: |
122 if newcobid in ListCobIDAvailable: |
267 raise ValueError, "Conflict type for location \"%s\"" % name |
123 ListCobIDAvailable.remove(newcobid) |
268 else: |
124 return newcobid, 0x1800 + nbSlavePDO |
269 # Get only the part of the location that concern this node |
125 return ListCobIDAvailable.pop(0), 0x1800 + nbSlavePDO |
270 loc = location["LOC"][len(current_location):] |
126 |
271 # loc correspond to (ID, INDEX, SUBINDEX [,BIT]) |
127 for number in xrange(4): |
272 if len(loc) not in (3, 4): |
128 if type == RPDO: |
273 raise ValueError, "Bad location size : %s"%str(loc) |
129 # For the fourth PDO -> cobid = 0x200 + ( numPdo * 0x100) + nodeid |
274 |
130 newcobid = (0x200 + number * 0x100 + nodeid) |
275 direction = location["DIR"] |
131 elif type == TPDO: |
276 |
132 # For the fourth PDO -> cobid = 0x180 + (numPdo * 0x100) + nodeid |
277 sizelocation = location["SIZE"] |
133 newcobid = (0x180 + number * 0x100 + nodeid) |
278 |
134 else: |
279 # Extract and check nodeid |
135 return None |
280 nodeid, index, subindex = loc[:3] |
136 if newcobid in ListCobIDAvailable: |
281 |
137 ListCobIDAvailable.remove(newcobid) |
282 # Check Id is in slave node list |
138 return newcobid |
283 if nodeid not in nodelist.SlaveNodes.keys(): |
139 return ListCobIDAvailable.pop(0) |
284 raise ValueError, "Non existing node ID : %d (variable %s)" % (nodeid,name) |
140 |
285 |
141 |
286 # Get the model for this node (made from EDS) |
|
287 node = nodelist.SlaveNodes[nodeid]["Node"] |
|
288 |
|
289 # Extract and check index and subindex |
|
290 if not node.IsEntry(index, subindex): |
|
291 raise ValueError, "No such index/subindex (%x,%x) in ID : %d (variable %s)" % (index,subindex,nodeid,name) |
|
292 |
|
293 #Get the entry info |
|
294 subentry_infos = node.GetSubentryInfos(index, subindex) |
|
295 |
|
296 # If a PDO mappable |
|
297 if subentry_infos and subentry_infos["pdo"]: |
|
298 if sizelocation == "X" and len(loc) > 3: |
|
299 numbit = loc[4] |
|
300 elif sizelocation != "X" and len(loc) > 3: |
|
301 raise ValueError, "Cannot set bit offset for non bool '%s' variable (ID:%d,Idx:%x,sIdx:%x))" % (name,nodeid,index,subindex) |
|
302 else: |
|
303 numbit = None |
|
304 |
|
305 entryinfos = node.GetSubentryInfos(index, subindex) |
|
306 if entryinfos["type"] != COlocationtype: |
|
307 raise ValueError, "Invalid type \"%s\"-> %d != %d for location\"%s\"" % (location["IEC_TYPE"], COlocationtype, entryinfos["type"] , name) |
|
308 |
|
309 typeinfos = node.GetEntryInfos(COlocationtype) |
|
310 DictLocations[name] = {"type":COlocationtype, "pdotype":SlavePDOType[direction], |
|
311 "nodeid": nodeid, "index": index,"subindex": subindex, |
|
312 "bit": numbit, "size": typeinfos["size"], "sizelocation": sizelocation} |
|
313 else: |
|
314 raise ValueError, "Not PDO mappable variable : '%s' (ID:%d,Idx:%x,sIdx:%x))" % (name,nodeid,index,subindex) |
|
315 |
|
316 # Create DictCobID with variables already mapped and add them in DictValidLocations |
|
317 for name, locationinfos in DictLocations.items(): |
|
318 node = self.NodeList.SlaveNodes[locationinfos["nodeid"]]["Node"] |
|
319 result = SearchNodePDOMapping(locationinfos, node) |
|
320 if result != None: |
|
321 index, subindex = result |
|
322 cobid = nodelist.GetSlaveNodeEntry(locationinfos["nodeid"], index - 0x200, 1) |
|
323 |
|
324 transmittype = nodelist.GetSlaveNodeEntry(locationinfos["nodeid"], index - 0x200, 2) |
|
325 |
|
326 if transmittype != sync_TPDOs: |
|
327 if sync_TPDOs : # Change TransmitType to ASYCHRONE |
|
328 node = nodelist.SlaveNodes[nodeid]["Node"] |
|
329 nodeDCF = masternode.GetEntry(0x1F22, nodeid) |
|
330 |
|
331 if nodeDCF != None and nodeDCF != '': |
|
332 tmpnbparams = [i for i in nodeDCF[:4]] |
|
333 tmpnbparams.reverse() |
|
334 nbparams = int(''.join(["%2.2x"%ord(i) for i in tmpnbparams]), 16) |
|
335 dataparams = nodeDCF[4:] |
|
336 else: |
|
337 nbparams = 0 |
|
338 dataparams = "" |
|
339 |
|
340 else: # Change TransmitType to SYNCHRONE |
|
341 pass |
|
342 |
|
343 |
|
344 if cobid not in DictCobID.keys(): |
|
345 mapping = [None] |
|
346 values = node.GetEntry(index) |
|
347 for value in values[1:]: |
|
348 mapping.append(value % 0x100) |
|
349 DictCobID[cobid] = {"type" : InvertPDOType[locationinfos["pdotype"]], "mapping" : mapping} |
|
350 |
|
351 DictCobID[cobid]["mapping"][subindex] = (locationinfos["type"], name) |
|
352 |
|
353 else: |
|
354 if locationinfos["nodeid"] not in DictLocationsNotMapped.keys(): |
|
355 DictLocationsNotMapped[locationinfos["nodeid"]] = {TPDO : [], RPDO : []} |
|
356 DictLocationsNotMapped[locationinfos["nodeid"]][locationinfos["pdotype"]].append((name, locationinfos)) |
|
357 |
|
358 #------------------------------------------------------------------------------- |
|
359 # Build concise DCF for the others locations |
|
360 #------------------------------------------------------------------------------- |
|
361 |
|
362 for nodeid, locations in DictLocationsNotMapped.items(): |
|
363 # Get current concise DCF |
|
364 node = nodelist.SlaveNodes[nodeid]["Node"] |
|
365 nodeDCF = masternode.GetEntry(0x1F22, nodeid) |
|
366 |
|
367 if nodeDCF != None and nodeDCF != '': |
|
368 tmpnbparams = [i for i in nodeDCF[:4]] |
|
369 tmpnbparams.reverse() |
|
370 nbparams = int(''.join(["%2.2x"%ord(i) for i in tmpnbparams]), 16) |
|
371 dataparams = nodeDCF[4:] |
|
372 else: |
|
373 nbparams = 0 |
|
374 dataparams = "" |
|
375 |
|
376 for pdotype in (TPDO, RPDO): |
|
377 pdosize = 0 |
|
378 pdomapping = [] |
|
379 for name, loc_infos in locations[pdotype]: |
|
380 pdosize += loc_infos["size"] |
|
381 # If pdo's size > 64 bits |
|
382 if pdosize > 64: |
|
383 result = GetNewCobID(nodeid, pdotype) |
|
384 if result: |
|
385 SlavesPdoNumber[nodeid][pdotype] += 1 |
|
386 new_cobid, new_idx = result |
|
387 data, nbaddedparams = GenerateMappingDCF(new_cobid, new_idx, pdomapping, False) |
|
388 dataparams += data |
|
389 nbparams += nbaddedparams |
|
390 DictCobID[new_cobid] = {"type" : InvertPDOType[pdotype], "mapping" : GenerateMasterMapping(pdomapping)} |
|
391 pdosize = loc_infos["size"] |
|
392 pdomapping = [(name, loc_infos)] |
|
393 else: |
|
394 pdomapping.append((name, loc_infos)) |
|
395 if len(pdomapping) > 0: |
|
396 result = GetNewCobID(nodeid, pdotype) |
|
397 if result: |
|
398 SlavesPdoNumber[nodeid][pdotype] += 1 |
|
399 new_cobid, new_idx = result |
|
400 data, nbaddedparams = GenerateMappingDCF(new_cobid, new_idx, pdomapping, False) |
|
401 dataparams += data |
|
402 nbparams += nbaddedparams |
|
403 DictCobID[new_cobid] = {"type" : InvertPDOType[pdotype], "mapping" : GenerateMasterMapping(pdomapping)} |
|
404 |
|
405 dcf = LE_to_BE(nbparams, 0x04) + dataparams |
|
406 masternode.SetEntry(0x1F22, nodeid, dcf) |
|
407 |
|
408 |
|
409 #------------------------------------------------------------------------------- |
|
410 # Master Node Configuration |
|
411 #------------------------------------------------------------------------------- |
|
412 |
|
413 |
|
414 |
|
415 # Configure Master's PDO parameters entries and set cobid, transmit type |
|
416 for cobid, pdo_infos in DictCobID.items(): |
|
417 current_idx = CurrentPDOParamsIdx[pdo_infos["type"]] |
|
418 addinglist = [current_idx, current_idx + 0x200] |
|
419 manager.ManageEntriesOfCurrent(addinglist, [], masternode) |
|
420 masternode.SetEntry(current_idx, 0x01, cobid) |
|
421 masternode.SetEntry(current_idx, 0x02, DefaultTransmitTypeMaster) |
|
422 if len(pdo_infos["mapping"]) > 2: |
|
423 manager.AddSubentriesToCurrent(current_idx + 0x200, len(pdo_infos["mapping"]) - 2, masternode) |
|
424 |
|
425 # Create Master's PDO mapping |
|
426 for subindex, variable in enumerate(pdo_infos["mapping"]): |
|
427 if subindex == 0: |
|
428 continue |
|
429 new_index = False |
|
430 |
|
431 if type(variable) != IntType: |
|
432 |
|
433 typeidx, varname = variable |
|
434 indexname = \ |
|
435 DictNameVariable[DictLocations[variable[1]]["pdotype"]][0] + \ |
|
436 DictLocations[variable[1]]["sizelocation"] + \ |
|
437 '_'.join(map(str,current_location)) + \ |
|
438 "_" + \ |
|
439 str(DictLocations[variable[1]]["nodeid"]) |
|
440 mapvariableidx = DictNameVariable[DictLocations[variable[1]]["pdotype"]][1] + DictNameVariable[DictLocations[variable[1]]["sizelocation"]] * DictNameVariable["increment"] |
|
441 |
|
442 #indexname = DictNameVariable[DictLocations[variable[1]]["pdotype"]][0] + DictLocations[variable[1]]["sizelocation"] + str(DictLocations[variable[1]]["prefix"]) + "_" + str(DictLocations[variable[1]]["nodeid"]) |
|
443 #mapvariableidx = DictNameVariable[DictLocations[variable[1]]["pdotype"]][1] + DictNameVariable[DictLocations[variable[1]]["sizelocation"]] * DictNameVariable["increment"] |
|
444 |
|
445 if not masternode.IsEntry(mapvariableidx): |
|
446 manager.AddMapVariableToCurrent(mapvariableidx, indexname, 3, 1, masternode) |
|
447 new_index = True |
|
448 nbsubentries = masternode.GetEntry(mapvariableidx, 0x00) |
|
449 else: |
|
450 nbsubentries = masternode.GetEntry(mapvariableidx, 0x00) |
|
451 mapvariableidxbase = mapvariableidx |
|
452 while mapvariableidx < (mapvariableidxbase + 0x1FF) and nbsubentries == 0xFF: |
|
453 mapvariableidx += 0x800 |
|
454 if not manager.IsCurrentEntry(mapvariableidx): |
|
455 manager.AddMapVariableToCurrent(mapvariableidx, indexname, 3, 1, masternode) |
|
456 new_index = True |
|
457 nbsubentries = masternode.GetEntry(mapvariableidx, 0x00) |
|
458 |
|
459 if mapvariableidx < 0x6000: |
|
460 if DictLocations[variable[1]]["bit"] != None: |
|
461 subindexname = str(DictLocations[variable[1]]["index"]) + "_" + str(DictLocations[variable[1]]["subindex"]) + "_" + str(DictLocations[variable[1]]["bit"]) |
|
462 else: |
|
463 subindexname = str(DictLocations[variable[1]]["index"]) + "_" + str(DictLocations[variable[1]]["subindex"]) |
|
464 if not new_index: |
|
465 manager.AddSubentriesToCurrent(mapvariableidx, 1, masternode) |
|
466 nbsubentries += 1 |
|
467 masternode.SetMappingEntry(mapvariableidx, nbsubentries, values = {"name" : subindexname}) |
|
468 masternode.SetMappingEntry(mapvariableidx, nbsubentries, values = {"type" : typeidx}) |
|
469 |
|
470 # Map Variable |
|
471 typeinfos = manager.GetEntryInfos(typeidx) |
|
472 if typeinfos != None: |
|
473 value = (mapvariableidx << 16) + ((nbsubentries) << 8) + typeinfos["size"] |
|
474 masternode.SetEntry(current_idx + 0x200, subindex, value) |
|
475 else: |
|
476 masternode.SetEntry(current_idx + 0x200, subindex, TrashVariableValue[variable]) |
|
477 |
|
478 CurrentPDOParamsIdx[pdo_infos["type"]] += 1 |
|
479 |
|
480 |
142 def GenerateConciseDCF(locations, current_location, nodelist, sync_TPDOs): |
481 def GenerateConciseDCF(locations, current_location, nodelist, sync_TPDOs): |
143 """ |
482 """ |
144 Fills a CanFestival network editor model, with DCF with requested PDO mappings. |
483 Fills a CanFestival network editor model, with DCF with requested PDO mappings. |
145 @param locations: List of complete variables locations \ |
484 @param locations: List of complete variables locations \ |
146 [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...) |
485 [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...) |
151 }, ...] |
490 }, ...] |
152 @param nodelist: CanFestival network editor model |
491 @param nodelist: CanFestival network editor model |
153 @return: a modified copy of the given CanFestival network editor model |
492 @return: a modified copy of the given CanFestival network editor model |
154 """ |
493 """ |
155 |
494 |
156 global DictLocations, DictCobID, DictLocationsNotMapped, ListCobIDAvailable, SlavesPdoNumber, DefaultTransmitTypeSlave |
495 dcfgenerator = ConciseDCFGenerator(nodelist) |
157 |
496 dcfgenerator.GenerateDCF(locations, current_location, sync_TPDOs) |
158 DictLocations = {} |
497 return dcfgenerator.GetMasterNode() |
159 DictCobID = {} |
498 |
160 DictLocationsNotMapped = {} |
499 if __name__ == "__main__": |
161 DictSDOparams = {} |
|
162 ListCobIDAvailable = range(0x180, 0x580) |
|
163 SlavesPdoNumber = {} |
|
164 DictNameVariable = { "" : 1, "X": 2, "B": 3, "W": 4, "D": 5, "L": 6, "increment": 0x100, 1:("__I", 0x2000), 2:("__Q", 0x4000)} |
|
165 DefaultTransmitTypeSlave = 0xFF |
|
166 # Master Node initialisation |
|
167 |
|
168 manager = nodelist.Manager |
|
169 masternode = manager.GetCurrentNodeCopy() |
|
170 if not masternode.IsEntry(0x1F22): |
|
171 masternode.AddEntry(0x1F22, 1, "") |
|
172 manager.AddSubentriesToCurrent(0x1F22, 127, masternode) |
|
173 # Adding trash mappable variables for unused mapped datas |
|
174 idxTrashVariables = 0x2000 + masternode.GetNodeID() |
|
175 TrashVariableValue = {} |
|
176 manager.AddMapVariableToCurrent(idxTrashVariables, "trashvariables", 3, len(TrashVariableSizes), masternode) |
|
177 for subidx, (size, typeidx) in enumerate(TrashVariableSizes.items()): |
|
178 manager.SetCurrentEntry(idxTrashVariables, subidx + 1, "TRASH%d" % size, "name", None, masternode) |
|
179 manager.SetCurrentEntry(idxTrashVariables, subidx + 1, typeidx, "type", None, masternode) |
|
180 TrashVariableValue[size] = (idxTrashVariables << 16) + ((subidx + 1) << 8) + size |
|
181 |
|
182 |
|
183 # Extract Master Node current empty mapping index |
|
184 CurrentPDOParamsIdx = {RPDO : 0x1400 + len(GetSlavePDOIndexes(masternode, RPDO)), |
|
185 TPDO : 0x1800 + len(GetSlavePDOIndexes(masternode, TPDO))} |
|
186 |
|
187 # Get list of all Slave's CobID and Slave's default SDO server parameters |
|
188 for nodeid, nodeinfos in nodelist.SlaveNodes.items(): |
|
189 node = nodeinfos["Node"] |
|
190 node.SetNodeID(nodeid) |
|
191 DictSDOparams[nodeid] = {"RSDO" : node.GetEntry(0x1200,0x01), "TSDO" : node.GetEntry(0x1200,0x02)} |
|
192 slaveRpdoIndexes = GetSlavePDOIndexes(node, RPDO, True) |
|
193 slaveTpdoIndexes = GetSlavePDOIndexes(node, TPDO, True) |
|
194 SlavesPdoNumber[nodeid] = {RPDO : len(slaveRpdoIndexes), TPDO : len(slaveTpdoIndexes)} |
|
195 for PdoIdx in slaveRpdoIndexes + slaveTpdoIndexes: |
|
196 pdo_cobid = node.GetEntry(PdoIdx, 0x01) |
|
197 if pdo_cobid > 0x600 : |
|
198 pdo_cobid -= 0x80000000 |
|
199 if pdo_cobid in ListCobIDAvailable: |
|
200 ListCobIDAvailable.remove(pdo_cobid) |
|
201 |
|
202 # Get list of locations check if exists and mappables -> put them in DictLocations |
|
203 for location in locations: |
|
204 locationtype = location["IEC_TYPE"] |
|
205 name = location["NAME"] |
|
206 if name in DictLocations: |
|
207 if DictLocations[name]["type"] != DicoTypes[locationtype]: |
|
208 raise ValueError, "Conflict type for location \"%s\"" % name |
|
209 else: |
|
210 #get only the part of the location that concern this node |
|
211 loc = location["LOC"][len(current_location):] |
|
212 # loc correspond to (ID, INDEX, SUBINDEX [,BIT]) |
|
213 if len(loc) not in (3, 4): |
|
214 raise ValueError, "Bad location size : %s"%str(loc) |
|
215 |
|
216 direction = location["DIR"] |
|
217 |
|
218 sizelocation = location["SIZE"] |
|
219 |
|
220 # Extract and check nodeid |
|
221 nodeid, index, subindex = loc[:3] |
|
222 |
|
223 # Check Id is in slave node list |
|
224 if nodeid not in nodelist.SlaveNodes.keys(): |
|
225 raise ValueError, "Non existing node ID : %d (variable %s)" % (nodeid,name) |
|
226 |
|
227 # Get the model for this node (made from EDS) |
|
228 node = nodelist.SlaveNodes[nodeid]["Node"] |
|
229 |
|
230 # Extract and check index and subindex |
|
231 if not node.IsEntry(index, subindex): |
|
232 raise ValueError, "No such index/subindex (%x,%x) in ID : %d (variable %s)" % (index,subindex,nodeid,name) |
|
233 |
|
234 #Get the entry info |
|
235 subentry_infos = node.GetSubentryInfos(index, subindex) |
|
236 |
|
237 # If a PDO mappable |
|
238 if subentry_infos and subentry_infos["pdo"]: |
|
239 if sizelocation == "X" and len(loc) > 3: |
|
240 numbit = loc[4] |
|
241 elif sizelocation != "X" and len(loc) > 3: |
|
242 raise ValueError, "Cannot set bit offset for non bool '%s' variable (ID:%d,Idx:%x,sIdx:%x))" % (name,nodeid,index,subindex) |
|
243 else: |
|
244 numbit = None |
|
245 |
|
246 COlocationtype = DicoTypes[locationtype] |
|
247 entryinfos = node.GetSubentryInfos(index, subindex) |
|
248 if entryinfos["type"] != COlocationtype: |
|
249 raise ValueError, "Invalid type \"%s\"-> %d != %d for location\"%s\"" % (locationtype,COlocationtype, entryinfos["type"] , name) |
|
250 |
|
251 typeinfos = node.GetEntryInfos(COlocationtype) |
|
252 DictLocations[name] = {"type":COlocationtype, "pdotype":SlavePDOType[direction], |
|
253 "nodeid": nodeid, "index": index,"subindex": subindex, |
|
254 "bit": numbit, "size": typeinfos["size"], "sizelocation": sizelocation} |
|
255 else: |
|
256 raise ValueError, "Not PDO mappable variable : '%s' (ID:%d,Idx:%x,sIdx:%x))" % (name,nodeid,index,subindex) |
|
257 |
|
258 # Create DictCobID with variables already mapped and add them in DictValidLocations |
|
259 for name, locationinfos in DictLocations.items(): |
|
260 node = nodelist.SlaveNodes[locationinfos["nodeid"]]["Node"] |
|
261 result = SearchSlavePDOMapping(locationinfos, node) |
|
262 if result != None: |
|
263 index, subindex = result |
|
264 cobid = nodelist.GetSlaveNodeEntry(locationinfos["nodeid"], index - 0x200, 1) |
|
265 if cobid not in DictCobID.keys(): |
|
266 mapping = [None] |
|
267 values = node.GetEntry(index) |
|
268 for value in values[1:]: |
|
269 mapping.append(value % 0x100) |
|
270 DictCobID[cobid] = {"type" : InvertPDOType[locationinfos["pdotype"]], "mapping" : mapping} |
|
271 |
|
272 DictCobID[cobid]["mapping"][subindex] = (locationinfos["type"], name) |
|
273 |
|
274 else: |
|
275 if locationinfos["nodeid"] not in DictLocationsNotMapped.keys(): |
|
276 DictLocationsNotMapped[locationinfos["nodeid"]] = {TPDO : [], RPDO : []} |
|
277 DictLocationsNotMapped[locationinfos["nodeid"]][locationinfos["pdotype"]].append((name, locationinfos)) |
|
278 |
|
279 # Check Master Pdo parameters for cobid already used and remove it in ListCobIDAvailable |
|
280 ListPdoParams = [idx for idx in masternode.GetIndexes() if 0x1400 <= idx <= 0x15FF or 0x1800 <= idx <= 0x19FF] |
|
281 for idx in ListPdoParams: |
|
282 cobid = masternode.GetEntry(idx, 0x01) |
|
283 if cobid not in DictCobID.keys(): |
|
284 ListCobIDAvailable.pop(cobid) |
|
285 |
|
286 #------------------------------------------------------------------------------- |
|
287 # Build concise DCF for the others locations |
|
288 #------------------------------------------------------------------------------- |
|
289 |
|
290 for nodeid, locations in DictLocationsNotMapped.items(): |
|
291 # Get current concise DCF |
|
292 node = nodelist.SlaveNodes[nodeid]["Node"] |
|
293 nodeDCF = masternode.GetEntry(0x1F22, nodeid) |
|
294 |
|
295 if nodeDCF != None and nodeDCF != '': |
|
296 tmpnbparams = [i for i in nodeDCF[:4]] |
|
297 tmpnbparams.reverse() |
|
298 nbparams = int(''.join(["%2.2x"%ord(i) for i in tmpnbparams]), 16) |
|
299 dataparams = nodeDCF[4:] |
|
300 else: |
|
301 nbparams = 0 |
|
302 dataparams = "" |
|
303 |
|
304 for pdotype in (TPDO, RPDO): |
|
305 pdosize = 0 |
|
306 pdomapping = [] |
|
307 for name, loc_infos in locations[pdotype]: |
|
308 pdosize += loc_infos["size"] |
|
309 # If pdo's size > 64 bits |
|
310 if pdosize > 64: |
|
311 result = GetNewCobID(nodeid, pdotype) |
|
312 if result: |
|
313 SlavesPdoNumber[nodeid][pdotype] += 1 |
|
314 new_cobid, new_idx = result |
|
315 data, nbaddedparams = GenerateMappingDCF(new_cobid, new_idx, pdomapping, False) |
|
316 dataparams += data |
|
317 nbparams += nbaddedparams |
|
318 DictCobID[new_cobid] = {"type" : InvertPDOType[pdotype], "mapping" : GenerateMasterMapping(pdomapping)} |
|
319 pdosize = loc_infos["size"] |
|
320 pdomapping = [(name, loc_infos)] |
|
321 else: |
|
322 pdomapping.append((name, loc_infos)) |
|
323 if len(pdomapping) > 0: |
|
324 result = GetNewCobID(nodeid, pdotype) |
|
325 if result: |
|
326 SlavesPdoNumber[nodeid][pdotype] += 1 |
|
327 new_cobid, new_idx = result |
|
328 data, nbaddedparams = GenerateMappingDCF(new_cobid, new_idx, pdomapping, False) |
|
329 dataparams += data |
|
330 nbparams += nbaddedparams |
|
331 DictCobID[new_cobid] = {"type" : InvertPDOType[pdotype], "mapping" : GenerateMasterMapping(pdomapping)} |
|
332 |
|
333 dcf = LE_to_BE(nbparams, 0x04) + dataparams |
|
334 masternode.SetEntry(0x1F22, nodeid, dcf) |
|
335 |
|
336 |
|
337 #------------------------------------------------------------------------------- |
|
338 # Master Node Configuration |
|
339 #------------------------------------------------------------------------------- |
|
340 |
|
341 # Configure Master's SDO parameters entries |
|
342 for nodeid, SDOparams in DictSDOparams.items(): |
|
343 SdoClient_index = [0x1280 + nodeid] |
|
344 manager.ManageEntriesOfCurrent(SdoClient_index,[], masternode) |
|
345 if SDOparams["RSDO"] != None: |
|
346 RSDO_cobid = SDOparams["RSDO"] |
|
347 else: |
|
348 RSDO_cobid = 0x600 + nodeid |
|
349 |
|
350 if SDOparams["TSDO"] != None: |
|
351 TSDO_cobid = SDOparams["TSDO"] |
|
352 else: |
|
353 TSDO_cobid = 0x580 + nodeid |
|
354 |
|
355 masternode.SetEntry(SdoClient_index[0], 0x01, RSDO_cobid) |
|
356 masternode.SetEntry(SdoClient_index[0], 0x02, TSDO_cobid) |
|
357 masternode.SetEntry(SdoClient_index[0], 0x03, nodeid) |
|
358 |
|
359 # Configure Master's PDO parameters entries and set cobid, transmit type |
|
360 for cobid, pdo_infos in DictCobID.items(): |
|
361 current_idx = CurrentPDOParamsIdx[pdo_infos["type"]] |
|
362 addinglist = [current_idx, current_idx + 0x200] |
|
363 manager.ManageEntriesOfCurrent(addinglist, [], masternode) |
|
364 masternode.SetEntry(current_idx, 0x01, cobid) |
|
365 masternode.SetEntry(current_idx, 0x02, DefaultTransmitTypeMaster) |
|
366 if len(pdo_infos["mapping"]) > 2: |
|
367 manager.AddSubentriesToCurrent(current_idx + 0x200, len(pdo_infos["mapping"]) - 2, masternode) |
|
368 |
|
369 # Create Master's PDO mapping |
|
370 for subindex, variable in enumerate(pdo_infos["mapping"]): |
|
371 if subindex == 0: |
|
372 continue |
|
373 new_index = False |
|
374 |
|
375 if type(variable) != IntType: |
|
376 |
|
377 typeidx, varname = variable |
|
378 indexname = \ |
|
379 DictNameVariable[DictLocations[variable[1]]["pdotype"]][0] + \ |
|
380 DictLocations[variable[1]]["sizelocation"] + \ |
|
381 '_'.join(map(str,current_location)) + \ |
|
382 "_" + \ |
|
383 str(DictLocations[variable[1]]["nodeid"]) |
|
384 mapvariableidx = DictNameVariable[DictLocations[variable[1]]["pdotype"]][1] + DictNameVariable[DictLocations[variable[1]]["sizelocation"]] * DictNameVariable["increment"] |
|
385 |
|
386 #indexname = DictNameVariable[DictLocations[variable[1]]["pdotype"]][0] + DictLocations[variable[1]]["sizelocation"] + str(DictLocations[variable[1]]["prefix"]) + "_" + str(DictLocations[variable[1]]["nodeid"]) |
|
387 #mapvariableidx = DictNameVariable[DictLocations[variable[1]]["pdotype"]][1] + DictNameVariable[DictLocations[variable[1]]["sizelocation"]] * DictNameVariable["increment"] |
|
388 |
|
389 if not masternode.IsEntry(mapvariableidx): |
|
390 manager.AddMapVariableToCurrent(mapvariableidx, indexname, 3, 1, masternode) |
|
391 new_index = True |
|
392 nbsubentries = masternode.GetEntry(mapvariableidx, 0x00) |
|
393 else: |
|
394 nbsubentries = masternode.GetEntry(mapvariableidx, 0x00) |
|
395 mapvariableidxbase = mapvariableidx |
|
396 while mapvariableidx < (mapvariableidxbase + 0x1FF) and nbsubentries == 0xFF: |
|
397 mapvariableidx += 0x800 |
|
398 if not manager.IsCurrentEntry(mapvariableidx): |
|
399 manager.AddMapVariableToCurrent(mapvariableidx, indexname, 3, 1, masternode) |
|
400 new_index = True |
|
401 nbsubentries = masternode.GetEntry(mapvariableidx, 0x00) |
|
402 |
|
403 if mapvariableidx < 0x6000: |
|
404 if DictLocations[variable[1]]["bit"] != None: |
|
405 subindexname = str(DictLocations[variable[1]]["index"]) + "_" + str(DictLocations[variable[1]]["subindex"]) + "_" + str(DictLocations[variable[1]]["bit"]) |
|
406 else: |
|
407 subindexname = str(DictLocations[variable[1]]["index"]) + "_" + str(DictLocations[variable[1]]["subindex"]) |
|
408 if not new_index: |
|
409 manager.AddSubentriesToCurrent(mapvariableidx, 1, masternode) |
|
410 nbsubentries += 1 |
|
411 masternode.SetMappingEntry(mapvariableidx, nbsubentries, values = {"name" : subindexname}) |
|
412 masternode.SetMappingEntry(mapvariableidx, nbsubentries, values = {"type" : typeidx}) |
|
413 |
|
414 # Map Variable |
|
415 typeinfos = manager.GetEntryInfos(typeidx) |
|
416 if typeinfos != None: |
|
417 value = (mapvariableidx << 16) + ((nbsubentries) << 8) + typeinfos["size"] |
|
418 masternode.SetEntry(current_idx + 0x200, subindex, value) |
|
419 else: |
|
420 masternode.SetEntry(current_idx + 0x200, subindex, TrashVariableValue[variable]) |
|
421 |
|
422 CurrentPDOParamsIdx[pdo_infos["type"]] += 1 |
|
423 #masternode.Print() |
|
424 return masternode |
|
425 |
|
426 if __name__ == "__main__": |
|
427 from nodemanager import * |
500 from nodemanager import * |
428 from nodelist import * |
501 from nodelist import * |
429 import sys |
502 import sys |
430 |
503 |
431 manager = NodeManager(sys.path[0]) |
504 manager = NodeManager(sys.path[0]) |