34 RPDO = 1 |
34 RPDO = 1 |
35 TPDO = 2 |
35 TPDO = 2 |
36 |
36 |
37 SlavePDOType = {"I" : TPDO, "Q" : RPDO} |
37 SlavePDOType = {"I" : TPDO, "Q" : RPDO} |
38 InvertPDOType = {RPDO : TPDO, TPDO : RPDO} |
38 InvertPDOType = {RPDO : TPDO, TPDO : RPDO} |
|
39 PDOTypeBaseIndex = {RPDO : 0x1400, TPDO : 0x1800} |
|
40 PDOTypeBaseCobId = {RPDO : 0x200, TPDO : 0x180} |
39 |
41 |
40 VariableIncrement = 0x100 |
42 VariableIncrement = 0x100 |
41 VariableStartIndex = {TPDO : 0x2000, RPDO : 0x4000} |
43 VariableStartIndex = {TPDO : 0x2000, RPDO : 0x4000} |
42 VariableDirText = {TPDO : "__I", RPDO : "__Q"} |
44 VariableDirText = {TPDO : "__I", RPDO : "__Q"} |
43 VariableTypeOffset = dict(zip(["","X","B","W","D","L"], range(6))) |
45 VariableTypeOffset = dict(zip(["","X","B","W","D","L"], range(6))) |
44 |
46 |
45 TrashVariables = [(1, 0x01), (8, 0x05), (16, 0x06), (32, 0x07), (64, 0x1B)] |
47 TrashVariables = [(1, 0x01), (8, 0x05), (16, 0x06), (32, 0x07), (64, 0x1B)] |
|
48 |
|
49 #------------------------------------------------------------------------------- |
|
50 # Specific exception for PDO mapping errors |
|
51 #------------------------------------------------------------------------------- |
|
52 |
|
53 class PDOmappingException(Exception): |
|
54 pass |
|
55 |
46 |
56 |
47 def LE_to_BE(value, size): |
57 def LE_to_BE(value, size): |
48 """ |
58 """ |
49 Convert Little Endian to Big Endian |
59 Convert Little Endian to Big Endian |
50 @param value: value expressed in integer |
60 @param value: value expressed in integer |
107 @param pdomapping: list of PDO mappings |
117 @param pdomapping: list of PDO mappings |
108 @return: a tuple of value and number of parameters to add to DCF |
118 @return: a tuple of value and number of parameters to add to DCF |
109 """ |
119 """ |
110 |
120 |
111 # Create entry for RPDO or TPDO parameters and Disable PDO |
121 # Create entry for RPDO or TPDO parameters and Disable PDO |
112 dcfdata = LE_to_BE(idx, 2) + LE_to_BE(0x01, 1) + LE_to_BE(0x04, 4) + LE_to_BE((0x80000000 + cobid), 4) |
122 dcfdata = LE_to_BE(idx, 2) + LE_to_BE(0x01, 1) + LE_to_BE(0x04, 4) + LE_to_BE(0x80000000 + cobid, 4) |
113 # Set Transmit type synchrone |
123 # Set Transmit type synchrone |
114 dcfdata += LE_to_BE(idx, 2) + LE_to_BE(0x02, 1) + LE_to_BE(0x01, 4) + LE_to_BE(transmittype, 1) |
124 dcfdata += LE_to_BE(idx, 2) + LE_to_BE(0x02, 1) + LE_to_BE(0x01, 4) + LE_to_BE(transmittype, 1) |
115 # Re-Enable PDO |
125 # Re-Enable PDO |
116 # ---- INDEX ----- --- SUBINDEX ---- ----- SIZE ------ ------ DATA ------ |
126 # ---- INDEX ----- --- SUBINDEX ---- ----- SIZE ------ ------ DATA ------ |
117 dcfdata += LE_to_BE(idx, 2) + LE_to_BE(0x01, 1) + LE_to_BE(0x04, 4) + LE_to_BE(0x00000000 + cobid, 4) |
127 dcfdata += LE_to_BE(idx, 2) + LE_to_BE(0x01, 1) + LE_to_BE(0x04, 4) + LE_to_BE(cobid, 4) |
118 nbparams = 3 |
128 nbparams = 3 |
119 # Map Variables |
129 if len(pdomapping) > 0: |
120 for subindex, (name, loc_infos) in enumerate(pdomapping): |
130 dcfdata += LE_to_BE(idx + 0x200, 2) + LE_to_BE(0x00, 1) + LE_to_BE(0x01, 4) + LE_to_BE(len(pdomapping), 1) |
121 value = (loc_infos["index"] << 16) + (loc_infos["subindex"] << 8) + loc_infos["size"] |
|
122 dcfdata += LE_to_BE(idx + 0x200, 2) + LE_to_BE(subindex + 1, 1) + LE_to_BE(0x04, 4) + LE_to_BE(value, 4) |
|
123 nbparams += 1 |
131 nbparams += 1 |
|
132 # Map Variables |
|
133 for subindex, (name, loc_infos) in enumerate(pdomapping): |
|
134 value = (loc_infos["index"] << 16) + (loc_infos["subindex"] << 8) + loc_infos["size"] |
|
135 dcfdata += LE_to_BE(idx + 0x200, 2) + LE_to_BE(subindex + 1, 1) + LE_to_BE(0x04, 4) + LE_to_BE(value, 4) |
|
136 nbparams += 1 |
124 return dcfdata, nbparams |
137 return dcfdata, nbparams |
125 |
138 |
126 class ConciseDCFGenerator: |
139 class ConciseDCFGenerator: |
127 |
140 |
128 def __init__(self, nodelist, nodename): |
141 def __init__(self, nodelist, nodename): |
132 self.LocationsNotMapped = {} |
145 self.LocationsNotMapped = {} |
133 # Dictionary of location informations classed by name |
146 # Dictionary of location informations classed by name |
134 self.MasterMapping = {} |
147 self.MasterMapping = {} |
135 # List of COB IDs available |
148 # List of COB IDs available |
136 self.ListCobIDAvailable = range(0x180, 0x580) |
149 self.ListCobIDAvailable = range(0x180, 0x580) |
137 self.SlavesPdoNumber = {} |
|
138 # Dictionary of mapping value where unexpected variables are stored |
150 # Dictionary of mapping value where unexpected variables are stored |
139 self.TrashVariables = {} |
151 self.TrashVariables = {} |
140 # Dictionary of pointed variables |
152 # Dictionary of pointed variables |
141 self.PointedVariables = {} |
153 self.PointedVariables = {} |
142 |
154 |
204 node = nodeinfos["Node"] |
216 node = nodeinfos["Node"] |
205 node.SetNodeID(nodeid) |
217 node.SetNodeID(nodeid) |
206 |
218 |
207 RPDOnumber, TPDOnumber = self.RemoveUsedNodeCobId(node) |
219 RPDOnumber, TPDOnumber = self.RemoveUsedNodeCobId(node) |
208 |
220 |
209 # Store the number of TPDO and RPDO for this node |
|
210 self.SlavesPdoNumber[nodeid] = {RPDO : RPDOnumber, TPDO : TPDOnumber} |
|
211 |
|
212 # Get Slave's default SDO server parameters |
221 # Get Slave's default SDO server parameters |
213 RSDO_cobid = node.GetEntry(0x1200,0x01) |
222 RSDO_cobid = node.GetEntry(0x1200,0x01) |
214 if not RSDO_cobid: |
223 if not RSDO_cobid: |
215 RSDO_cobid = 0x600 + nodeid |
224 RSDO_cobid = 0x600 + nodeid |
216 TSDO_cobid = node.GetEntry(0x1200,0x02) |
225 TSDO_cobid = node.GetEntry(0x1200,0x02) |
227 def GetMasterNode(self): |
236 def GetMasterNode(self): |
228 """ |
237 """ |
229 Return MasterNode. |
238 Return MasterNode. |
230 """ |
239 """ |
231 return self.MasterNode |
240 return self.MasterNode |
232 |
|
233 |
|
234 def GetNewCobID(self, nodeid, type): |
|
235 """ |
|
236 Select a COB ID from the list of those available |
|
237 @param nodeid: id of the slave (int) |
|
238 @param type: type of PDO (RPDO or TPDO) |
|
239 @return: a tuple of the COD ID and PDO index or None |
|
240 """ |
|
241 # Verify that there is still some cobid available |
|
242 if len(self.ListCobIDAvailable) == 0: |
|
243 return None |
|
244 |
|
245 # Get the number of PDO of the type given for the node |
|
246 nbSlavePDO = self.SlavesPdoNumber[nodeid][type] |
|
247 if type == RPDO: |
|
248 if nbSlavePDO < 4: |
|
249 # For the four first RPDO -> cobid = 0x200 + ( numPdo parameters * 0x100) + nodeid |
|
250 newcobid = (0x200 + nbSlavePDO * 0x100 + nodeid) |
|
251 # Return calculated cobid if it's still available |
|
252 if newcobid in self.ListCobIDAvailable: |
|
253 self.ListCobIDAvailable.remove(newcobid) |
|
254 return newcobid, 0x1400 + nbSlavePDO |
|
255 # Return the first cobid available if no cobid found |
|
256 return self.ListCobIDAvailable.pop(0), 0x1400 + nbSlavePDO |
|
257 |
|
258 elif type == TPDO: |
|
259 if nbSlavePDO < 4: |
|
260 # For the four first TPDO -> cobid = 0x180 + ( numPdo parameters * 0x100) + nodeid |
|
261 newcobid = (0x180 + nbSlavePDO * 0x100 + nodeid) |
|
262 # Return calculated cobid if it's still available |
|
263 if newcobid in self.ListCobIDAvailable: |
|
264 self.ListCobIDAvailable.remove(newcobid) |
|
265 return newcobid, 0x1800 + nbSlavePDO |
|
266 # Return the first cobid available if no cobid found |
|
267 return self.ListCobIDAvailable.pop(0), 0x1800 + nbSlavePDO |
|
268 |
|
269 return None |
|
270 |
|
271 |
241 |
272 def AddParamsToDCF(self, nodeid, data, nbparams): |
242 def AddParamsToDCF(self, nodeid, data, nbparams): |
273 """ |
243 """ |
274 Add entry to DCF, for the requested nodeID |
244 Add entry to DCF, for the requested nodeID |
275 @param nodeid: id of the slave (int) |
245 @param nodeid: id of the slave (int) |
289 # Build new DCF |
259 # Build new DCF |
290 dcf = LE_to_BE(nbparams, 0x04) + data |
260 dcf = LE_to_BE(nbparams, 0x04) + data |
291 # Set new DCF for slave |
261 # Set new DCF for slave |
292 self.MasterNode.SetEntry(0x1F22, nodeid, dcf) |
262 self.MasterNode.SetEntry(0x1F22, nodeid, dcf) |
293 |
263 |
294 def AddPDOMapping(self, nodeid, pdotype, pdomapping, sync_TPDOs): |
264 def GetEmptyPDO(self, nodeid, pdotype, start_index=None): |
|
265 """ |
|
266 Search a not configured PDO for a slave |
|
267 @param node: the slave node object |
|
268 @param pdotype: type of PDO to generated (RPDO or TPDO) |
|
269 @param start_index: Index where search must start (default: None) |
|
270 @return tuple of PDO index, COB ID and number of subindex defined |
|
271 """ |
|
272 # If no start_index defined, start with PDOtype base index |
|
273 if start_index is None: |
|
274 index = PDOTypeBaseIndex[pdotype] |
|
275 else: |
|
276 index = start_index |
|
277 |
|
278 # Search for all PDO possible index until find a configurable PDO |
|
279 # starting from start_index |
|
280 while index < PDOTypeBaseIndex[pdotype] + 0x200: |
|
281 values = self.NodeList.GetSlaveNodeEntry(nodeid, index + 0x200) |
|
282 if values != None and values[0] > 0: |
|
283 # Check that all subindex upper than 0 equal 0 => configurable PDO |
|
284 if reduce(lambda x, y: x and y, map(lambda x: x == 0, values[1:]), True): |
|
285 cobid = self.NodeList.GetSlaveNodeEntry(nodeid, index, 1) |
|
286 # If no COB ID defined in PDO, generate a new one (not used) |
|
287 if cobid == 0: |
|
288 if len(self.ListCobIDAvailable) == 0: |
|
289 return None |
|
290 # Calculate COB ID from standard values |
|
291 if index < PDOTypeBaseIndex[pdotype] + 4: |
|
292 cobid = PDOTypeBaseCobId[pdotype] + 0x100 * (index - PDOTypeBaseIndex[pdotype]) + nodeid |
|
293 if cobid not in self.ListCobIDAvailable: |
|
294 cobid = self.ListCobIDAvailable.pop(0) |
|
295 return index, cobid, values[0] |
|
296 index += 1 |
|
297 return None |
|
298 |
|
299 def AddPDOMapping(self, nodeid, pdotype, pdoindex, pdocobid, pdomapping, sync_TPDOs): |
295 """ |
300 """ |
296 Record a new mapping request for a slave, and add related slave config to the DCF |
301 Record a new mapping request for a slave, and add related slave config to the DCF |
297 @param nodeid: id of the slave (int) |
302 @param nodeid: id of the slave (int) |
298 @param pdotype: type of PDO to generated (RPDO or TPDO) |
303 @param pdotype: type of PDO to generated (RPDO or TPDO) |
299 @param pdomapping: list od variables to map with PDO |
304 @param pdomapping: list od variables to map with PDO |
300 """ |
305 """ |
301 # Get a new cob id |
306 # Add an entry to MasterMapping |
302 result = self.GetNewCobID(nodeid, pdotype) |
307 self.MasterMapping[pdocobid] = {"type" : InvertPDOType[pdotype], |
303 if result: |
308 "mapping" : [None] + [(loc_infos["type"], name) for name, loc_infos in pdomapping]} |
304 new_cobid, new_idx = result |
309 |
305 |
310 # Return the data to add to DCF |
306 # Increment the number of PDO of this type for node |
311 if sync_TPDOs: |
307 self.SlavesPdoNumber[nodeid][pdotype] += 1 |
312 return GeneratePDOMappingDCF(pdoindex, pdocobid, 0x01, pdomapping) |
308 |
313 else: |
309 # Add an entry to MasterMapping |
314 return GeneratePDOMappingDCF(pdoindex, pdocobid, 0xFF, pdomapping) |
310 self.MasterMapping[new_cobid] = {"type" : InvertPDOType[pdotype], |
|
311 "mapping" : [None] + [(loc_infos["type"], name) for name, loc_infos in pdomapping]} |
|
312 |
|
313 # Return the data to add to DCF |
|
314 if sync_TPDOs: |
|
315 return GeneratePDOMappingDCF(new_idx, new_cobid, 0x01, pdomapping) |
|
316 else: |
|
317 return GeneratePDOMappingDCF(new_idx, new_cobid, 0xFF, pdomapping) |
|
318 return 0, "" |
315 return 0, "" |
319 |
316 |
320 def GenerateDCF(self, locations, current_location, sync_TPDOs): |
317 def GenerateDCF(self, locations, current_location, sync_TPDOs): |
321 """ |
318 """ |
322 Generate Concise DCF of MasterNode for the locations list given |
319 Generate Concise DCF of MasterNode for the locations list given |
333 for location in locations: |
330 for location in locations: |
334 COlocationtype = IECToCOType[location["IEC_TYPE"]] |
331 COlocationtype = IECToCOType[location["IEC_TYPE"]] |
335 name = location["NAME"] |
332 name = location["NAME"] |
336 if name in self.IECLocations: |
333 if name in self.IECLocations: |
337 if self.IECLocations[name]["type"] != COlocationtype: |
334 if self.IECLocations[name]["type"] != COlocationtype: |
338 raise ValueError, "Conflict type for location \"%s\"" % name |
335 raise PDOmappingException, "Conflict type for location \"%s\"" % name |
339 else: |
336 else: |
340 # Get only the part of the location that concern this node |
337 # Get only the part of the location that concern this node |
341 loc = location["LOC"][len(current_location):] |
338 loc = location["LOC"][len(current_location):] |
342 # loc correspond to (ID, INDEX, SUBINDEX [,BIT]) |
339 # loc correspond to (ID, INDEX, SUBINDEX [,BIT]) |
343 if len(loc) not in (2, 3, 4): |
340 if len(loc) not in (2, 3, 4): |
344 raise ValueError, "Bad location size : %s"%str(loc) |
341 raise PDOmappingException, "Bad location size : %s"%str(loc) |
345 elif len(loc) == 2: |
342 elif len(loc) == 2: |
346 continue |
343 continue |
347 |
344 |
348 direction = location["DIR"] |
345 direction = location["DIR"] |
349 |
346 |
352 # Extract and check nodeid |
349 # Extract and check nodeid |
353 nodeid, index, subindex = loc[:3] |
350 nodeid, index, subindex = loc[:3] |
354 |
351 |
355 # Check Id is in slave node list |
352 # Check Id is in slave node list |
356 if nodeid not in self.NodeList.SlaveNodes.keys(): |
353 if nodeid not in self.NodeList.SlaveNodes.keys(): |
357 raise ValueError, "Non existing node ID : %d (variable %s)" % (nodeid,name) |
354 raise PDOmappingException, "Non existing node ID : %d (variable %s)" % (nodeid,name) |
358 |
355 |
359 # Get the model for this node (made from EDS) |
356 # Get the model for this node (made from EDS) |
360 node = self.NodeList.SlaveNodes[nodeid]["Node"] |
357 node = self.NodeList.SlaveNodes[nodeid]["Node"] |
361 |
358 |
362 # Extract and check index and subindex |
359 # Extract and check index and subindex |
363 if not node.IsEntry(index, subindex): |
360 if not node.IsEntry(index, subindex): |
364 raise ValueError, "No such index/subindex (%x,%x) in ID : %d (variable %s)" % (index,subindex,nodeid,name) |
361 raise PDOmappingException, "No such index/subindex (%x,%x) in ID : %d (variable %s)" % (index,subindex,nodeid,name) |
365 |
362 |
366 # Get the entry info |
363 # Get the entry info |
367 subentry_infos = node.GetSubentryInfos(index, subindex) |
364 subentry_infos = node.GetSubentryInfos(index, subindex) |
368 |
365 |
369 # If a PDO mappable |
366 # If a PDO mappable |
370 if subentry_infos and subentry_infos["pdo"]: |
367 if subentry_infos and subentry_infos["pdo"]: |
371 if sizelocation == "X" and len(loc) > 3: |
368 if sizelocation == "X" and len(loc) > 3: |
372 numbit = loc[3] |
369 numbit = loc[3] |
373 elif sizelocation != "X" and len(loc) > 3: |
370 elif sizelocation != "X" and len(loc) > 3: |
374 raise ValueError, "Cannot set bit offset for non bool '%s' variable (ID:%d,Idx:%x,sIdx:%x))" % (name,nodeid,index,subindex) |
371 raise PDOmappingException, "Cannot set bit offset for non bool '%s' variable (ID:%d,Idx:%x,sIdx:%x))" % (name,nodeid,index,subindex) |
375 else: |
372 else: |
376 numbit = None |
373 numbit = None |
377 |
374 |
378 if location["IEC_TYPE"] != "BOOL" and subentry_infos["type"] != COlocationtype: |
375 if location["IEC_TYPE"] != "BOOL" and subentry_infos["type"] != COlocationtype: |
379 raise ValueError, "Invalid type \"%s\"-> %d != %d for location\"%s\"" % (location["IEC_TYPE"], COlocationtype, subentry_infos["type"] , name) |
376 raise PDOmappingException, "Invalid type \"%s\"-> %d != %d for location\"%s\"" % (location["IEC_TYPE"], COlocationtype, subentry_infos["type"] , name) |
380 |
377 |
381 typeinfos = node.GetEntryInfos(COlocationtype) |
378 typeinfos = node.GetEntryInfos(COlocationtype) |
382 self.IECLocations[name] = {"type":COlocationtype, "pdotype":SlavePDOType[direction], |
379 self.IECLocations[name] = {"type":COlocationtype, "pdotype":SlavePDOType[direction], |
383 "nodeid": nodeid, "index": index,"subindex": subindex, |
380 "nodeid": nodeid, "index": index,"subindex": subindex, |
384 "bit": numbit, "size": typeinfos["size"], "sizelocation": sizelocation} |
381 "bit": numbit, "size": typeinfos["size"], "sizelocation": sizelocation} |
385 else: |
382 else: |
386 raise ValueError, "Not PDO mappable variable : '%s' (ID:%d,Idx:%x,sIdx:%x))" % (name,nodeid,index,subindex) |
383 raise PDOmappingException, "Not PDO mappable variable : '%s' (ID:%d,Idx:%x,sIdx:%x))" % (name,nodeid,index,subindex) |
387 |
384 |
388 #------------------------------------------------------------------------------- |
385 #------------------------------------------------------------------------------- |
389 # Search for locations already mapped |
386 # Search for locations already mapped |
390 #------------------------------------------------------------------------------- |
387 #------------------------------------------------------------------------------- |
391 |
388 |
448 nbparams = 0 |
445 nbparams = 0 |
449 dataparams = "" |
446 dataparams = "" |
450 |
447 |
451 # Generate the best PDO mapping for each type of PDO |
448 # Generate the best PDO mapping for each type of PDO |
452 for pdotype in (TPDO, RPDO): |
449 for pdotype in (TPDO, RPDO): |
453 pdosize = 0 |
450 if len(locations[pdotype]) > 0: |
454 pdomapping = [] |
451 pdosize = 0 |
455 for name, loc_infos in locations[pdotype]: |
452 pdomapping = [] |
456 pdosize += loc_infos["size"] |
453 result = self.GetEmptyPDO(nodeid, pdotype) |
457 # If pdo's size > 64 bits |
454 if result is None: |
458 if pdosize > 64: |
455 raise PDOmappingException, "Impossible to define PDO mapping for node %02x"%nodeid |
|
456 pdoindex, pdocobid, pdonbparams = result |
|
457 for name, loc_infos in locations[pdotype]: |
|
458 pdosize += loc_infos["size"] |
|
459 # If pdo's size > 64 bits |
|
460 if pdosize > 64 or len(pdomapping) >= pdonbparams: |
|
461 # Generate a new PDO Mapping |
|
462 data, nbaddedparams = self.AddPDOMapping(nodeid, pdotype, pdoindex, pdocobid, pdomapping, sync_TPDOs) |
|
463 dataparams += data |
|
464 nbparams += nbaddedparams |
|
465 pdosize = loc_infos["size"] |
|
466 pdomapping = [(name, loc_infos)] |
|
467 result = self.GetEmptyPDO(nodeid, pdotype, pdoindex + 1) |
|
468 if result is None: |
|
469 raise PDOmappingException, "Impossible to define PDO mapping for node %02x"%nodeid |
|
470 pdoindex, pdocobid, pdonbparams = result |
|
471 else: |
|
472 pdomapping.append((name, loc_infos)) |
|
473 # If there isn't locations yet but there is still a PDO to generate |
|
474 if len(pdomapping) > 0: |
459 # Generate a new PDO Mapping |
475 # Generate a new PDO Mapping |
460 data, nbaddedparams = self.AddPDOMapping(nodeid, pdotype, pdomapping, sync_TPDOs) |
476 data, nbaddedparams = self.AddPDOMapping(nodeid, pdotype, pdoindex, pdocobid, pdomapping, sync_TPDOs) |
461 dataparams += data |
477 dataparams += data |
462 nbparams += nbaddedparams |
478 nbparams += nbaddedparams |
463 pdosize = loc_infos["size"] |
479 |
464 pdomapping = [(name, loc_infos)] |
|
465 else: |
|
466 pdomapping.append((name, loc_infos)) |
|
467 # If there isn't locations yet but there is still a PDO to generate |
|
468 if len(pdomapping) > 0: |
|
469 # Generate a new PDO Mapping |
|
470 data, nbaddedparams = self.AddPDOMapping(nodeid, pdotype, pdomapping, sync_TPDOs) |
|
471 dataparams += data |
|
472 nbparams += nbaddedparams |
|
473 |
|
474 # Add number of params and data to node DCF |
480 # Add number of params and data to node DCF |
475 self.AddParamsToDCF(nodeid, dataparams, nbparams) |
481 self.AddParamsToDCF(nodeid, dataparams, nbparams) |
476 |
482 |
477 #------------------------------------------------------------------------------- |
483 #------------------------------------------------------------------------------- |
478 # Master Node Configuration |
484 # Master Node Configuration |
606 for location in locations: |
612 for location in locations: |
607 COlocationtype = IECToCOType[location["IEC_TYPE"]] |
613 COlocationtype = IECToCOType[location["IEC_TYPE"]] |
608 name = location["NAME"] |
614 name = location["NAME"] |
609 if name in IECLocations: |
615 if name in IECLocations: |
610 if IECLocations[name] != COlocationtype: |
616 if IECLocations[name] != COlocationtype: |
611 raise ValueError, "Conflict type for location \"%s\"" % name |
617 raise PDOmappingException, "Conflict type for location \"%s\"" % name |
612 else: |
618 else: |
613 # Get only the part of the location that concern this node |
619 # Get only the part of the location that concern this node |
614 loc = location["LOC"][len(current_location):] |
620 loc = location["LOC"][len(current_location):] |
615 # loc correspond to (ID, INDEX, SUBINDEX [,BIT]) |
621 # loc correspond to (ID, INDEX, SUBINDEX [,BIT]) |
616 if len(loc) not in (2, 3, 4): |
622 if len(loc) not in (2, 3, 4): |
617 raise ValueError, "Bad location size : %s"%str(loc) |
623 raise PDOmappingException, "Bad location size : %s"%str(loc) |
618 elif len(loc) != 2: |
624 elif len(loc) != 2: |
619 continue |
625 continue |
620 |
626 |
621 # Extract and check nodeid |
627 # Extract and check nodeid |
622 index, subindex = loc[:2] |
628 index, subindex = loc[:2] |
623 |
629 |
624 # Extract and check index and subindex |
630 # Extract and check index and subindex |
625 if not slave.IsEntry(index, subindex): |
631 if not slave.IsEntry(index, subindex): |
626 raise ValueError, "No such index/subindex (%x,%x) (variable %s)" % (index, subindex, name) |
632 raise PDOmappingException, "No such index/subindex (%x,%x) (variable %s)" % (index, subindex, name) |
627 |
633 |
628 # Get the entry info |
634 # Get the entry info |
629 subentry_infos = slave.GetSubentryInfos(index, subindex) |
635 subentry_infos = slave.GetSubentryInfos(index, subindex) |
630 if subentry_infos["type"] != COlocationtype: |
636 if subentry_infos["type"] != COlocationtype: |
631 raise ValueError, "Invalid type \"%s\"-> %d != %d for location\"%s\"" % (location["IEC_TYPE"], COlocationtype, subentry_infos["type"] , name) |
637 raise PDOmappingException, "Invalid type \"%s\"-> %d != %d for location\"%s\"" % (location["IEC_TYPE"], COlocationtype, subentry_infos["type"] , name) |
632 |
638 |
633 IECLocations[name] = COlocationtype |
639 IECLocations[name] = COlocationtype |
634 pointers[(index, subindex)] = name |
640 pointers[(index, subindex)] = name |
635 return pointers |
641 return pointers |
636 |
642 |