50 |
50 |
51 # --------------------- for master --------------------------- |
51 # --------------------- for master --------------------------- |
52 MASTER_STATE = """ |
52 MASTER_STATE = """ |
53 import commands |
53 import commands |
54 result = commands.getoutput("ethercat master") |
54 result = commands.getoutput("ethercat master") |
55 returnVal =result |
55 returnVal =result |
56 """ |
56 """ |
57 |
57 |
58 # --------------------- for slave ---------------------------- |
58 # --------------------- for slave ---------------------------- |
59 # ethercat state -p (slave position) (state (INIT, PREOP, SAFEOP, OP)) |
59 # ethercat state -p (slave position) (state (INIT, PREOP, SAFEOP, OP)) |
60 SLAVE_STATE = """ |
60 SLAVE_STATE = """ |
61 import commands |
61 import commands |
62 result = commands.getoutput("ethercat state -p %d %s") |
62 result = commands.getoutput("ethercat state -p %d %s") |
63 returnVal = result |
63 returnVal = result |
64 """ |
64 """ |
65 |
65 |
66 # ethercat slave |
66 # ethercat slave |
67 GET_SLAVE = """ |
67 GET_SLAVE = """ |
68 import commands |
68 import commands |
69 result = commands.getoutput("ethercat slaves") |
69 result = commands.getoutput("ethercat slaves") |
70 returnVal =result |
70 returnVal =result |
71 """ |
71 """ |
72 |
72 |
73 # ethercat xml -p (slave position) |
73 # ethercat xml -p (slave position) |
74 SLAVE_XML = """ |
74 SLAVE_XML = """ |
75 import commands |
75 import commands |
76 result = commands.getoutput("ethercat xml -p %d") |
76 result = commands.getoutput("ethercat xml -p %d") |
77 returnVal = result |
77 returnVal = result |
78 """ |
78 """ |
79 |
79 |
80 # ethercat sdos -p (slave position) |
80 # ethercat sdos -p (slave position) |
81 SLAVE_SDO = """ |
81 SLAVE_SDO = """ |
82 import commands |
82 import commands |
83 result = commands.getoutput("ethercat sdos -p %d") |
83 result = commands.getoutput("ethercat sdos -p %d") |
84 returnVal =result |
84 returnVal =result |
85 """ |
85 """ |
86 |
86 |
87 # ethercat upload -p (slave position) (main index) (sub index) |
87 # ethercat upload -p (slave position) (main index) (sub index) |
88 GET_SLOW_SDO = """ |
88 GET_SLOW_SDO = """ |
89 import commands |
89 import commands |
90 result = commands.getoutput("ethercat upload -p %d %s %s") |
90 result = commands.getoutput("ethercat upload -p %d %s %s") |
91 returnVal =result |
91 returnVal =result |
92 """ |
92 """ |
93 |
93 |
94 # ethercat download -p (slave position) (main index) (sub index) (value) |
94 # ethercat download -p (slave position) (main index) (sub index) (value) |
95 SDO_DOWNLOAD = """ |
95 SDO_DOWNLOAD = """ |
96 import commands |
96 import commands |
97 result = commands.getoutput("ethercat download --type %s -p %d %s %s %s") |
97 result = commands.getoutput("ethercat download --type %s -p %d %s %s %s") |
98 returnVal =result |
98 returnVal =result |
99 """ |
99 """ |
100 |
100 |
101 # ethercat sii_read -p (slave position) |
101 # ethercat sii_read -p (slave position) |
102 SII_READ = """ |
102 SII_READ = """ |
103 import commands |
103 import commands |
104 result = commands.getoutput("ethercat sii_read -p %d") |
104 result = commands.getoutput("ethercat sii_read -p %d") |
105 returnVal =result |
105 returnVal =result |
106 """ |
106 """ |
107 |
107 |
108 # ethercat reg_read -p (slave position) (address) (size) |
108 # ethercat reg_read -p (slave position) (address) (size) |
109 REG_READ = """ |
109 REG_READ = """ |
110 import commands |
110 import commands |
111 result = commands.getoutput("ethercat reg_read -p %d %s %s") |
111 result = commands.getoutput("ethercat reg_read -p %d %s %s") |
112 returnVal =result |
112 returnVal =result |
113 """ |
113 """ |
114 |
114 |
115 # ethercat sii_write -p (slave position) - (contents) |
115 # ethercat sii_write -p (slave position) - (contents) |
116 SII_WRITE = """ |
116 SII_WRITE = """ |
117 import subprocess |
117 import subprocess |
118 process = subprocess.Popen( |
118 process = subprocess.Popen( |
119 ["ethercat", "-f", "sii_write", "-p", "%d", "-"], |
119 ["ethercat", "-f", "sii_write", "-p", "%d", "-"], |
120 stdin=subprocess.PIPE) |
120 stdin=subprocess.PIPE) |
121 process.communicate(sii_data) |
121 process.communicate(sii_data) |
122 returnVal = process.returncode |
122 returnVal = process.returncode |
123 """ |
123 """ |
124 |
124 |
125 # ethercat reg_write -p (slave position) -t (uinit16) (address) (data) |
125 # ethercat reg_write -p (slave position) -t (uinit16) (address) (data) |
126 REG_WRITE = """ |
126 REG_WRITE = """ |
127 import commands |
127 import commands |
128 result = commands.getoutput("ethercat reg_write -p %d -t uint16 %s %s") |
128 result = commands.getoutput("ethercat reg_write -p %d -t uint16 %s %s") |
129 returnVal =result |
129 returnVal =result |
130 """ |
130 """ |
131 |
131 |
132 # ethercat rescan -p (slave position) |
132 # ethercat rescan -p (slave position) |
133 RESCAN = """ |
133 RESCAN = """ |
134 import commands |
134 import commands |
135 result = commands.getoutput("ethercat rescan -p %d") |
135 result = commands.getoutput("ethercat rescan -p %d") |
136 returnVal =result |
136 returnVal =result |
137 """ |
137 """ |
138 |
138 |
139 #-------------------------------------------------- |
139 #-------------------------------------------------- |
140 # Common Method For EtherCAT Management |
140 # Common Method For EtherCAT Management |
141 #-------------------------------------------------- |
141 #-------------------------------------------------- |
142 class _CommonSlave: |
142 class _CommonSlave: |
143 |
143 |
144 # ----- Data Structure for ethercat management ---- |
144 # ----- Data Structure for ethercat management ---- |
145 SlaveState = "" |
145 SlaveState = "" |
146 |
146 |
147 # category of SDO data |
147 # category of SDO data |
148 DatatypeDescription, CommunicationObject, ManufacturerSpecific, \ |
148 DatatypeDescription, CommunicationObject, ManufacturerSpecific, \ |
149 ProfileSpecific, Reserved, AllSDOData = range(6) |
149 ProfileSpecific, Reserved, AllSDOData = range(6) |
150 |
150 |
151 # store the execution result of "ethercat sdos" command into SaveSDOData. |
151 # store the execution result of "ethercat sdos" command into SaveSDOData. |
152 SaveSDOData = [] |
152 SaveSDOData = [] |
153 |
153 |
154 # Flags for checking "write" permission of OD entries |
154 # Flags for checking "write" permission of OD entries |
155 CheckPREOP = False |
155 CheckPREOP = False |
156 CheckSAFEOP = False |
156 CheckSAFEOP = False |
157 CheckOP = False |
157 CheckOP = False |
158 |
158 |
159 # Save PDO Data |
159 # Save PDO Data |
160 TxPDOInfo = [] |
160 TxPDOInfo = [] |
161 TxPDOCategory = [] |
161 TxPDOCategory = [] |
162 RxPDOInfo = [] |
162 RxPDOInfo = [] |
163 RxPDOCategory = [] |
163 RxPDOCategory = [] |
164 |
164 |
165 # Save EEPROM Data |
165 # Save EEPROM Data |
166 SiiData = "" |
166 SiiData = "" |
167 |
167 |
168 # Save Register Data |
168 # Save Register Data |
169 RegData = "" |
169 RegData = "" |
170 CrtRegSpec = {"ESCType": "", |
170 CrtRegSpec = {"ESCType": "", |
171 "FMMUNumber": "", |
171 "FMMUNumber": "", |
172 "SMNumber": "", |
172 "SMNumber": "", |
173 "PDIType": ""} |
173 "PDIType": ""} |
174 |
174 |
175 def __init__(self, controler): |
175 def __init__(self, controler): |
176 """ |
176 """ |
177 Constructor |
177 Constructor |
178 @param controler: _EthercatSlaveCTN class in EthercatSlave.py |
178 @param controler: _EthercatSlaveCTN class in EthercatSlave.py |
179 """ |
179 """ |
180 self.Controler = controler |
180 self.Controler = controler |
181 |
181 |
182 self.ClearSDODataSet() |
182 self.ClearSDODataSet() |
183 |
183 |
184 #------------------------------------------------------------------------------- |
184 #------------------------------------------------------------------------------- |
185 # Used Master State |
185 # Used Master State |
186 #------------------------------------------------------------------------------- |
186 #------------------------------------------------------------------------------- |
187 def GetMasterState(self): |
187 def GetMasterState(self): |
188 """ |
188 """ |
189 Execute "ethercat master" command and parse the execution result |
189 Execute "ethercat master" command and parse the execution result |
190 @return MasterState |
190 @return MasterState |
191 """ |
191 """ |
192 |
192 |
193 # exectute "ethercat master" command |
193 # exectute "ethercat master" command |
194 error, return_val = self.Controler.RemoteExec(MASTER_STATE, return_val = None) |
194 error, return_val = self.Controler.RemoteExec(MASTER_STATE, return_val = None) |
195 master_state = {} |
195 master_state = {} |
196 # parse the reslut |
196 # parse the reslut |
197 for each_line in return_val.splitlines(): |
197 for each_line in return_val.splitlines(): |
198 if len(each_line) > 0 : |
198 if len(each_line) > 0 : |
202 if len(chunks) > 1 : |
202 if len(chunks) > 1 : |
203 value = chunks[1].split() |
203 value = chunks[1].split() |
204 if '(attached)' in value: |
204 if '(attached)' in value: |
205 value.remove('(attached)') |
205 value.remove('(attached)') |
206 master_state[key] = value |
206 master_state[key] = value |
207 |
207 |
208 return master_state |
208 return master_state |
209 |
209 |
210 #------------------------------------------------------------------------------- |
210 #------------------------------------------------------------------------------- |
211 # Used Slave State |
211 # Used Slave State |
212 #------------------------------------------------------------------------------- |
212 #------------------------------------------------------------------------------- |
213 def RequestSlaveState(self, command): |
213 def RequestSlaveState(self, command): |
214 """ |
214 """ |
215 Set slave state to the specified one using "ethercat states -p %d %s" command. |
215 Set slave state to the specified one using "ethercat states -p %d %s" command. |
216 Command example : "ethercat states -p 0 PREOP" (target slave position and target state are given.) |
216 Command example : "ethercat states -p 0 PREOP" (target slave position and target state are given.) |
217 @param command : target slave state |
217 @param command : target slave state |
218 """ |
218 """ |
219 error, return_val = self.Controler.RemoteExec(SLAVE_STATE%(self.Controler.GetSlavePos(), command), return_val = None) |
219 error, return_val = self.Controler.RemoteExec(SLAVE_STATE%(self.Controler.GetSlavePos(), command), return_val = None) |
220 |
220 |
221 def GetSlaveStateFromSlave(self): |
221 def GetSlaveStateFromSlave(self): |
222 """ |
222 """ |
223 Get slave information using "ethercat slaves" command and store the information into internal data structure |
223 Get slave information using "ethercat slaves" command and store the information into internal data structure |
224 (self.SlaveState) for "Slave State" |
224 (self.SlaveState) for "Slave State" |
225 return_val example : 0 0:0 PREOP + EL9800 (V4.30) (PIC24, SPI, ET1100) |
225 return_val example : 0 0:0 PREOP + EL9800 (V4.30) (PIC24, SPI, ET1100) |
226 """ |
226 """ |
227 error, return_val = self.Controler.RemoteExec(GET_SLAVE, return_val = None) |
227 error, return_val = self.Controler.RemoteExec(GET_SLAVE, return_val = None) |
228 self.SlaveState = return_val |
228 self.SlaveState = return_val |
229 return return_val |
229 return return_val |
230 |
230 |
231 #------------------------------------------------------------------------------- |
231 #------------------------------------------------------------------------------- |
232 # Used SDO Management |
232 # Used SDO Management |
233 #------------------------------------------------------------------------------- |
233 #------------------------------------------------------------------------------- |
234 def GetSlaveSDOFromSlave(self): |
234 def GetSlaveSDOFromSlave(self): |
235 """ |
235 """ |
236 Get SDO objects information of current slave using "ethercat sdos -p %d" command. |
236 Get SDO objects information of current slave using "ethercat sdos -p %d" command. |
237 Command example : "ethercat sdos -p 0" |
237 Command example : "ethercat sdos -p 0" |
238 @return return_val : execution results of "ethercat sdos" command (need to be parsed later) |
238 @return return_val : execution results of "ethercat sdos" command (need to be parsed later) |
239 """ |
239 """ |
240 error, return_val = self.Controler.RemoteExec(SLAVE_SDO%(self.Controler.GetSlavePos()), return_val = None) |
240 error, return_val = self.Controler.RemoteExec(SLAVE_SDO%(self.Controler.GetSlavePos()), return_val = None) |
241 return return_val |
241 return return_val |
242 |
242 |
243 def SDODownload(self, data_type, idx, sub_idx, value): |
243 def SDODownload(self, data_type, idx, sub_idx, value): |
244 """ |
244 """ |
245 Set an SDO object value to user-specified value using "ethercat download" command. |
245 Set an SDO object value to user-specified value using "ethercat download" command. |
246 Command example : "ethercat download --type int32 -p 0 0x8020 0x12 0x00000000" |
246 Command example : "ethercat download --type int32 -p 0 0x8020 0x12 0x00000000" |
247 @param data_type : data type of SDO entry |
247 @param data_type : data type of SDO entry |
248 @param idx : index of the SDO entry |
248 @param idx : index of the SDO entry |
249 @param sub_idx : subindex of the SDO entry |
249 @param sub_idx : subindex of the SDO entry |
250 @param value : value of SDO entry |
250 @param value : value of SDO entry |
251 """ |
251 """ |
252 error, return_val = self.Controler.RemoteExec(SDO_DOWNLOAD%(data_type, self.Controler.GetSlavePos(), idx, sub_idx, value), return_val = None) |
252 error, return_val = self.Controler.RemoteExec(SDO_DOWNLOAD%(data_type, self.Controler.GetSlavePos(), idx, sub_idx, value), return_val = None) |
253 |
253 |
254 def BackupSDODataSet(self): |
254 def BackupSDODataSet(self): |
255 """ |
255 """ |
256 Back-up current SDO entry information to restore the SDO data |
256 Back-up current SDO entry information to restore the SDO data |
257 in case that the user cancels SDO update operation. |
257 in case that the user cancels SDO update operation. |
258 """ |
258 """ |
259 self.BackupDatatypeDescription = self.SaveDatatypeDescription |
259 self.BackupDatatypeDescription = self.SaveDatatypeDescription |
260 self.BackupCommunicationObject = self.SaveCommunicationObject |
260 self.BackupCommunicationObject = self.SaveCommunicationObject |
261 self.BackupManufacturerSpecific = self.SaveManufacturerSpecific |
261 self.BackupManufacturerSpecific = self.SaveManufacturerSpecific |
262 self.BackupProfileSpecific = self.SaveProfileSpecific |
262 self.BackupProfileSpecific = self.SaveProfileSpecific |
263 self.BackupReserved = self.SaveReserved |
263 self.BackupReserved = self.SaveReserved |
264 self.BackupAllSDOData = self.SaveAllSDOData |
264 self.BackupAllSDOData = self.SaveAllSDOData |
265 |
265 |
266 def ClearSDODataSet(self): |
266 def ClearSDODataSet(self): |
267 """ |
267 """ |
268 Clear the specified SDO entry information. |
268 Clear the specified SDO entry information. |
269 """ |
269 """ |
270 for count in range(6): |
270 for count in range(6): |
271 self.SaveSDOData.append([]) |
271 self.SaveSDOData.append([]) |
272 |
272 |
273 #------------------------------------------------------------------------------- |
273 #------------------------------------------------------------------------------- |
274 # Used PDO Monitoring |
274 # Used PDO Monitoring |
275 #------------------------------------------------------------------------------- |
275 #------------------------------------------------------------------------------- |
276 def RequestPDOInfo(self): |
276 def RequestPDOInfo(self): |
277 """ |
277 """ |
278 Load slave information from RootClass (XML data) and parse the information (calling SlavePDOData() method). |
278 Load slave information from RootClass (XML data) and parse the information (calling SlavePDOData() method). |
279 """ |
279 """ |
280 # Load slave information from ESI XML file (def EthercatMaster.py) |
280 # Load slave information from ESI XML file (def EthercatMaster.py) |
281 slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) |
281 slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) |
282 |
282 |
283 type_infos = slave.getType() |
283 type_infos = slave.getType() |
284 device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) |
284 device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) |
285 # Initialize PDO data set |
285 # Initialize PDO data set |
286 self.ClearDataSet() |
286 self.ClearDataSet() |
287 |
287 |
288 # if 'device' object is valid, call SavePDOData() to parse PDO data |
288 # if 'device' object is valid, call SavePDOData() to parse PDO data |
289 if device is not None : |
289 if device is not None : |
290 self.SavePDOData(device) |
290 self.SavePDOData(device) |
291 |
291 |
292 def SavePDOData(self, device): |
292 def SavePDOData(self, device): |
293 """ |
293 """ |
294 Parse PDO data and store the results in TXPDOCategory and RXPDOCategory |
294 Parse PDO data and store the results in TXPDOCategory and RXPDOCategory |
295 Tx(Rx)PDOCategory : index, name, entry number |
295 Tx(Rx)PDOCategory : index, name, entry number |
296 Tx(Rx)Info : entry index, sub index, name, length, type |
296 Tx(Rx)Info : entry index, sub index, name, length, type |
297 @param device : Slave information extracted from ESI XML file |
297 @param device : Slave information extracted from ESI XML file |
298 """ |
298 """ |
299 # Parsing TXPDO entries |
299 # Parsing TXPDO entries |
300 for pdo, pdo_info in ([(pdo, "Inputs") for pdo in device.getTxPdo()]): |
300 for pdo, pdo_info in ([(pdo, "Inputs") for pdo in device.getTxPdo()]): |
301 # Save pdo_index, entry, and name of each entry |
301 # Save pdo_index, entry, and name of each entry |
302 pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) |
302 pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) |
303 entries = pdo.getEntry() |
303 entries = pdo.getEntry() |
304 pdo_name = ExtractName(pdo.getName()) |
304 pdo_name = ExtractName(pdo.getName()) |
305 |
305 |
306 # Initialize entry number count |
306 # Initialize entry number count |
307 count = 0 |
307 count = 0 |
308 |
308 |
309 # Parse entries |
309 # Parse entries |
310 for entry in entries: |
310 for entry in entries: |
311 # Save index and subindex |
311 # Save index and subindex |
312 index = ExtractHexDecValue(entry.getIndex().getcontent()) |
312 index = ExtractHexDecValue(entry.getIndex().getcontent()) |
313 subindex = ExtractHexDecValue(entry.getSubIndex()) |
313 subindex = ExtractHexDecValue(entry.getSubIndex()) |
320 "bitlen" : entry.getBitLen(), |
320 "bitlen" : entry.getBitLen(), |
321 "type" : entry.getDataType().getcontent() |
321 "type" : entry.getDataType().getcontent() |
322 } |
322 } |
323 self.TxPDOInfo.append(entry_infos) |
323 self.TxPDOInfo.append(entry_infos) |
324 count += 1 |
324 count += 1 |
325 |
325 |
326 categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count} |
326 categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count} |
327 self.TxPDOCategory.append(categorys) |
327 self.TxPDOCategory.append(categorys) |
328 |
328 |
329 # Parsing RxPDO entries |
329 # Parsing RxPDO entries |
330 for pdo, pdo_info in ([(pdo, "Outputs") for pdo in device.getRxPdo()]): |
330 for pdo, pdo_info in ([(pdo, "Outputs") for pdo in device.getRxPdo()]): |
331 # Save pdo_index, entry, and name of each entry |
331 # Save pdo_index, entry, and name of each entry |
332 pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) |
332 pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) |
333 entries = pdo.getEntry() |
333 entries = pdo.getEntry() |
334 pdo_name = ExtractName(pdo.getName()) |
334 pdo_name = ExtractName(pdo.getName()) |
335 |
335 |
336 # Initialize entry number count |
336 # Initialize entry number count |
337 count = 0 |
337 count = 0 |
338 |
338 |
339 # Parse entries |
339 # Parse entries |
340 for entry in entries: |
340 for entry in entries: |
341 # Save index and subindex |
341 # Save index and subindex |
342 index = ExtractHexDecValue(entry.getIndex().getcontent()) |
342 index = ExtractHexDecValue(entry.getIndex().getcontent()) |
343 subindex = ExtractHexDecValue(entry.getSubIndex()) |
343 subindex = ExtractHexDecValue(entry.getSubIndex()) |
344 # if entry name exists, save entry data |
344 # if entry name exists, save entry data |
350 "bitlen" : str(entry.getBitLen()), |
350 "bitlen" : str(entry.getBitLen()), |
351 "type" : entry.getDataType().getcontent() |
351 "type" : entry.getDataType().getcontent() |
352 } |
352 } |
353 self.RxPDOInfo.append(entry_infos) |
353 self.RxPDOInfo.append(entry_infos) |
354 count += 1 |
354 count += 1 |
355 |
355 |
356 categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count} |
356 categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count} |
357 self.RxPDOCategory.append(categorys) |
357 self.RxPDOCategory.append(categorys) |
358 |
358 |
359 def GetTxPDOCategory(self): |
359 def GetTxPDOCategory(self): |
360 """ |
360 """ |
361 Get TxPDOCategory data structure (Meta informaton of TxPDO). |
361 Get TxPDOCategory data structure (Meta informaton of TxPDO). |
362 TxPDOCategorys : index, name, number of entries |
362 TxPDOCategorys : index, name, number of entries |
363 @return TxPDOCategorys |
363 @return TxPDOCategorys |
364 """ |
364 """ |
365 return self.TxPDOCategory |
365 return self.TxPDOCategory |
366 |
366 |
367 def GetRxPDOCategory(self): |
367 def GetRxPDOCategory(self): |
368 """ |
368 """ |
369 Get RxPDOCategory data structure (Meta information of RxPDO). |
369 Get RxPDOCategory data structure (Meta information of RxPDO). |
370 RxPDOCategorys : index, name, number of entries |
370 RxPDOCategorys : index, name, number of entries |
371 @return RxPDOCategorys |
371 @return RxPDOCategorys |
372 """ |
372 """ |
373 return self.RxPDOCategory |
373 return self.RxPDOCategory |
374 |
374 |
375 def GetTxPDOInfo(self): |
375 def GetTxPDOInfo(self): |
376 """ |
376 """ |
377 Get TxPDOInfo data structure (Detailed information on TxPDO entries). |
377 Get TxPDOInfo data structure (Detailed information on TxPDO entries). |
378 TxPDOInfos : entry index, sub index, name, length, type |
378 TxPDOInfos : entry index, sub index, name, length, type |
379 @return TxPDOInfos |
379 @return TxPDOInfos |
380 """ |
380 """ |
381 return self.TxPDOInfo |
381 return self.TxPDOInfo |
382 |
382 |
383 def GetRxPDOInfo(self): |
383 def GetRxPDOInfo(self): |
384 """ |
384 """ |
385 Get RxPDOInfo data structure (Detailed information on RxPDO entries). |
385 Get RxPDOInfo data structure (Detailed information on RxPDO entries). |
386 RxPDOInfos : entry index, sub index, name, length, type |
386 RxPDOInfos : entry index, sub index, name, length, type |
387 @return RxPDOInfos |
387 @return RxPDOInfos |
388 """ |
388 """ |
389 return self.RxPDOInfo |
389 return self.RxPDOInfo |
390 |
390 |
391 def ClearDataSet(self): |
391 def ClearDataSet(self): |
392 """ |
392 """ |
393 Initialize PDO management data structure. |
393 Initialize PDO management data structure. |
394 """ |
394 """ |
395 self.TxPDOInfos = [] |
395 self.TxPDOInfos = [] |
396 self.TxPDOCategorys = [] |
396 self.TxPDOCategorys = [] |
397 self.RxPDOInfos = [] |
397 self.RxPDOInfos = [] |
398 self.RxPDOCategorys = [] |
398 self.RxPDOCategorys = [] |
399 |
399 |
400 #------------------------------------------------------------------------------- |
400 #------------------------------------------------------------------------------- |
401 # Used EEPROM Management |
401 # Used EEPROM Management |
402 #------------------------------------------------------------------------------- |
402 #------------------------------------------------------------------------------- |
403 # Base data types in ETG2000; format = {"Name": "BitSize"} |
403 # Base data types in ETG2000; format = {"Name": "BitSize"} |
404 BaseDataTypeDict = {"BOOL": "01", |
404 BaseDataTypeDict = {"BOOL": "01", |
453 "mailbox_bootstrapconf_inlength": '0', |
453 "mailbox_bootstrapconf_inlength": '0', |
454 "mailbox_standardconf_outstart": '0', |
454 "mailbox_standardconf_outstart": '0', |
455 "mailbox_standardconf_outlength": '0', |
455 "mailbox_standardconf_outlength": '0', |
456 "mailbox_standardconf_instart": '0', |
456 "mailbox_standardconf_instart": '0', |
457 "mailbox_standardconf_inlength": '0'} |
457 "mailbox_standardconf_inlength": '0'} |
458 |
458 |
459 slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) |
459 slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) |
460 type_infos = slave.getType() |
460 type_infos = slave.getType() |
461 device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) |
461 device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) |
462 |
462 |
463 # 'device' represents current slave device selected by user |
463 # 'device' represents current slave device selected by user |
464 if device is not None: |
464 if device is not None: |
465 for eeprom_element in device.getEeprom().getcontent(): |
465 for eeprom_element in device.getEeprom().getcontent(): |
466 # get EEPROM size; <Device>-<Eeprom>-<ByteSize> |
466 # get EEPROM size; <Device>-<Eeprom>-<ByteSize> |
467 if eeprom_element["name"] == "ByteSize": |
467 if eeprom_element["name"] == "ByteSize": |
468 smartview_infos["eeprom_size"] = eeprom_element |
468 smartview_infos["eeprom_size"] = eeprom_element |
469 |
469 |
470 elif eeprom_element["name"] == "ConfigData": |
470 elif eeprom_element["name"] == "ConfigData": |
471 configData_data = self.DecimalToHex(eeprom_element) |
471 configData_data = self.DecimalToHex(eeprom_element) |
472 # get PDI type; <Device>-<Eeprom>-<ConfigData> address 0x00 |
472 # get PDI type; <Device>-<Eeprom>-<ConfigData> address 0x00 |
473 smartview_infos["pdi_type"] = int(configData_data[0:2], 16) |
473 smartview_infos["pdi_type"] = int(configData_data[0:2], 16) |
474 # get state of device emulation; <Device>-<Eeprom>-<ConfigData> address 0x01 |
474 # get state of device emulation; <Device>-<Eeprom>-<ConfigData> address 0x01 |
476 smartview_infos["device_emulation"] = "True" |
476 smartview_infos["device_emulation"] = "True" |
477 |
477 |
478 elif eeprom_element["name"] == "BootStrap": |
478 elif eeprom_element["name"] == "BootStrap": |
479 bootstrap_data = "{:0>16x}".format(eeprom_element) |
479 bootstrap_data = "{:0>16x}".format(eeprom_element) |
480 # get bootstrap configuration; <Device>-<Eeprom>-<BootStrap> |
480 # get bootstrap configuration; <Device>-<Eeprom>-<BootStrap> |
481 for cfg, iter in [("mailbox_bootstrapconf_outstart", 0), |
481 for cfg, iter in [("mailbox_bootstrapconf_outstart", 0), |
482 ("mailbox_bootstrapconf_outlength", 1), |
482 ("mailbox_bootstrapconf_outlength", 1), |
483 ("mailbox_bootstrapconf_instart", 2), |
483 ("mailbox_bootstrapconf_instart", 2), |
484 ("mailbox_bootstrapconf_inlength", 3)]: |
484 ("mailbox_bootstrapconf_inlength", 3)]: |
485 smartview_infos[cfg] = str(int(bootstrap_data[4*iter+2:4*(iter+1)]+bootstrap_data[4*iter:4*iter+2], 16)) |
485 smartview_infos[cfg] = str(int(bootstrap_data[4*iter+2:4*(iter+1)]+bootstrap_data[4*iter:4*iter+2], 16)) |
486 |
486 |
487 # get protocol (profile) types supported by mailbox; <Device>-<Mailbox> |
487 # get protocol (profile) types supported by mailbox; <Device>-<Mailbox> |
488 mb = device.getMailbox() |
488 mb = device.getMailbox() |
489 if mb is not None: |
489 if mb is not None: |
490 for mailbox_protocol in mailbox_protocols: |
490 for mailbox_protocol in mailbox_protocols: |
491 if getattr(mb,"get%s"%mailbox_protocol)() is not None: |
491 if getattr(mb,"get%s"%mailbox_protocol)() is not None: |
492 smartview_infos["supported_mailbox"] += "%s, "%mailbox_protocol |
492 smartview_infos["supported_mailbox"] += "%s, "%mailbox_protocol |
493 smartview_infos["supported_mailbox"] = smartview_infos["supported_mailbox"].strip(", ") |
493 smartview_infos["supported_mailbox"] = smartview_infos["supported_mailbox"].strip(", ") |
494 |
494 |
495 # get standard configuration of mailbox; <Device>-<Sm> |
495 # get standard configuration of mailbox; <Device>-<Sm> |
496 for sm_element in device.getSm(): |
496 for sm_element in device.getSm(): |
497 if sm_element.getcontent() == "MBoxOut": |
497 if sm_element.getcontent() == "MBoxOut": |
498 smartview_infos["mailbox_standardconf_outstart"] = str(ExtractHexDecValue(sm_element.getStartAddress())) |
498 smartview_infos["mailbox_standardconf_outstart"] = str(ExtractHexDecValue(sm_element.getStartAddress())) |
499 smartview_infos["mailbox_standardconf_outlength"] = str(ExtractHexDecValue(sm_element.getDefaultSize())) |
499 smartview_infos["mailbox_standardconf_outlength"] = str(ExtractHexDecValue(sm_element.getDefaultSize())) |
508 # if device type in 'vendor' item equals to actual slave device type, set 'vendor_id' to vendor ID. |
508 # if device type in 'vendor' item equals to actual slave device type, set 'vendor_id' to vendor ID. |
509 for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): |
509 for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): |
510 for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]: |
510 for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]: |
511 if available_device[0] == type_infos["device_type"]: |
511 if available_device[0] == type_infos["device_type"]: |
512 smartview_infos["vendor_id"] = "0x" + "{:0>8x}".format(vendor_id) |
512 smartview_infos["vendor_id"] = "0x" + "{:0>8x}".format(vendor_id) |
513 |
513 |
514 # product code; |
514 # product code; |
515 if device.getType().getProductCode() is not None: |
515 if device.getType().getProductCode() is not None: |
516 product_code = device.getType().getProductCode() |
516 product_code = device.getType().getProductCode() |
517 smartview_infos["product_code"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(product_code)) |
517 smartview_infos["product_code"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(product_code)) |
518 |
518 |
519 # revision number; |
519 # revision number; |
520 if device.getType().getRevisionNo() is not None: |
520 if device.getType().getRevisionNo() is not None: |
521 revision_no = device.getType().getRevisionNo() |
521 revision_no = device.getType().getRevisionNo() |
522 smartview_infos["revision_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(revision_no)) |
522 smartview_infos["revision_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(revision_no)) |
523 |
523 |
524 # serial number; |
524 # serial number; |
525 if device.getType().getSerialNo() is not None: |
525 if device.getType().getSerialNo() is not None: |
526 serial_no = device.getType().getSerialNo() |
526 serial_no = device.getType().getSerialNo() |
527 smartview_infos["serial_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(serial_no)) |
527 smartview_infos["serial_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(serial_no)) |
528 |
528 |
529 return smartview_infos |
529 return smartview_infos |
530 |
530 |
531 else: |
531 else: |
532 return None |
532 return None |
533 |
533 |
534 def DecimalToHex(self, decnum): |
534 def DecimalToHex(self, decnum): |
535 """ |
535 """ |
536 Convert decimal value into hexadecimal representation. |
536 Convert decimal value into hexadecimal representation. |
537 @param decnum : decimal value |
537 @param decnum : decimal value |
538 @return hex_data : hexadecimal representation of input value in decimal |
538 @return hex_data : hexadecimal representation of input value in decimal |
539 """ |
539 """ |
540 value = "%x" % decnum |
540 value = "%x" % decnum |
541 value_len = len(value) |
541 value_len = len(value) |
542 if (value_len % 2) == 0: |
542 if (value_len % 2) == 0: |
543 hex_len = value_len |
543 hex_len = value_len |
544 else: |
544 else: |
545 hex_len = (value_len / 2) * 2 + 2 |
545 hex_len = (value_len / 2) * 2 + 2 |
546 |
546 |
547 hex_data = ("{:0>"+str(hex_len)+"x}").format(decnum) |
547 hex_data = ("{:0>"+str(hex_len)+"x}").format(decnum) |
548 |
548 |
549 return hex_data |
549 return hex_data |
550 |
550 |
551 def SiiRead(self): |
551 def SiiRead(self): |
552 """ |
552 """ |
553 Get slave EEPROM contents maintained by master device using "ethercat sii_read -p %d" command. |
553 Get slave EEPROM contents maintained by master device using "ethercat sii_read -p %d" command. |
554 Command example : "ethercat sii_read -p 0" |
554 Command example : "ethercat sii_read -p 0" |
555 @return return_val : result of "ethercat sii_read" (binary data) |
555 @return return_val : result of "ethercat sii_read" (binary data) |
556 """ |
556 """ |
557 error, return_val = self.Controler.RemoteExec(SII_READ%(self.Controler.GetSlavePos()), return_val = None) |
557 error, return_val = self.Controler.RemoteExec(SII_READ%(self.Controler.GetSlavePos()), return_val = None) |
558 self.SiiData = return_val |
558 self.SiiData = return_val |
559 return return_val |
559 return return_val |
560 |
560 |
561 def SiiWrite(self, binary): |
561 def SiiWrite(self, binary): |
562 """ |
562 """ |
563 Overwrite slave EEPROM contents using "ethercat sii_write -p %d" command. |
563 Overwrite slave EEPROM contents using "ethercat sii_write -p %d" command. |
564 Command example : "ethercat sii_write -p 0 - (binary contents)" |
564 Command example : "ethercat sii_write -p 0 - (binary contents)" |
565 @param binary : EEPROM contents in binary data format |
565 @param binary : EEPROM contents in binary data format |
566 @return return_val : result of "ethercat sii_write" (If it succeeds, the return value is NULL.) |
566 @return return_val : result of "ethercat sii_write" (If it succeeds, the return value is NULL.) |
567 """ |
567 """ |
568 error, return_val = self.Controler.RemoteExec(SII_WRITE%(self.Controler.GetSlavePos()), return_val = None, sii_data = binary) |
568 error, return_val = self.Controler.RemoteExec(SII_WRITE%(self.Controler.GetSlavePos()), return_val = None, sii_data = binary) |
569 return return_val |
569 return return_val |
570 |
570 |
571 def LoadData(self): |
571 def LoadData(self): |
572 """ |
572 """ |
573 Loading data from EEPROM use Sii_Read Method |
573 Loading data from EEPROM use Sii_Read Method |
574 @return self.BinaryCode : slave EEPROM data in binary format (zero-padded) |
574 @return self.BinaryCode : slave EEPROM data in binary format (zero-padded) |
575 """ |
575 """ |
576 return_val = self.Controler.CommonMethod.SiiRead() |
576 return_val = self.Controler.CommonMethod.SiiRead() |
577 self.BinaryCode = return_val |
577 self.BinaryCode = return_val |
578 self.Controler.SiiData = self.BinaryCode |
578 self.Controler.SiiData = self.BinaryCode |
579 |
579 |
580 # append zero-filled padding data up to EEPROM size |
580 # append zero-filled padding data up to EEPROM size |
581 for index in range(self.SmartViewInfosFromXML["eeprom_size"] - len(self.BinaryCode)): |
581 for index in range(self.SmartViewInfosFromXML["eeprom_size"] - len(self.BinaryCode)): |
582 self.BinaryCode = self.BinaryCode +'ff'.decode('hex') |
582 self.BinaryCode = self.BinaryCode +'ff'.decode('hex') |
583 |
583 |
584 return self.BinaryCode |
584 return self.BinaryCode |
585 |
585 |
586 def HexRead(self, binary): |
586 def HexRead(self, binary): |
587 """ |
587 """ |
588 Convert binary digit representation into hexadecimal representation for "Hex View" menu. |
588 Convert binary digit representation into hexadecimal representation for "Hex View" menu. |
589 @param binary : binary digits |
589 @param binary : binary digits |
590 @return hexCode : hexadecimal digits |
590 @return hexCode : hexadecimal digits |
591 @return hexview_table_row, hexview_table_col : Grid size for "Hex View" UI |
591 @return hexview_table_row, hexview_table_col : Grid size for "Hex View" UI |
592 """ |
592 """ |
593 row_code = [] |
593 row_code = [] |
594 row_text = "" |
594 row_text = "" |
595 row = 0 |
595 row = 0 |
596 hex_code = [] |
596 hex_code = [] |
597 |
597 |
598 hexview_table_col = 17 |
598 hexview_table_col = 17 |
599 |
599 |
600 for index in range(0, len(binary)) : |
600 for index in range(0, len(binary)) : |
601 if len(binary[index]) != 1: |
601 if len(binary[index]) != 1: |
602 break |
602 break |
603 else: |
603 else: |
604 digithexstr = hex(ord(binary[index])) |
604 digithexstr = hex(ord(binary[index])) |
605 |
605 |
606 tempvar2 = digithexstr[2:4] |
606 tempvar2 = digithexstr[2:4] |
607 if len(tempvar2) == 1: |
607 if len(tempvar2) == 1: |
608 tempvar2 = "0" + tempvar2 |
608 tempvar2 = "0" + tempvar2 |
609 row_code.append(tempvar2) |
609 row_code.append(tempvar2) |
610 |
610 |
611 if int(digithexstr, 16)>=32 and int(digithexstr, 16)<=126: |
611 if int(digithexstr, 16)>=32 and int(digithexstr, 16)<=126: |
612 row_text = row_text + chr(int(digithexstr, 16)) |
612 row_text = row_text + chr(int(digithexstr, 16)) |
613 else: |
613 else: |
614 row_text = row_text + "." |
614 row_text = row_text + "." |
615 |
615 |
616 if index != 0 : |
616 if index != 0 : |
617 if len(row_code) == (hexview_table_col - 1): |
617 if len(row_code) == (hexview_table_col - 1): |
618 row_code.append(row_text) |
618 row_code.append(row_text) |
619 hex_code.append(row_code) |
619 hex_code.append(row_code) |
620 row_text = "" |
620 row_text = "" |
621 row_code = [] |
621 row_code = [] |
622 row = row + 1 |
622 row = row + 1 |
623 |
623 |
624 hexview_table_row = row |
624 hexview_table_row = row |
625 |
625 |
626 return hex_code, hexview_table_row, hexview_table_col |
626 return hex_code, hexview_table_row, hexview_table_col |
627 |
627 |
628 def GenerateEEPROMList(self, data, direction, length): |
628 def GenerateEEPROMList(self, data, direction, length): |
629 """ |
629 """ |
630 Generate EEPROM data list by reconstructing 'data' string. |
630 Generate EEPROM data list by reconstructing 'data' string. |
631 example : data="12345678", direction=0, length=8 -> eeprom_list=['12', '34', '56', '78'] |
631 example : data="12345678", direction=0, length=8 -> eeprom_list=['12', '34', '56', '78'] |
632 data="12345678", direction=1, length=8 -> eeprom_list=['78', '56', '34', '12'] |
632 data="12345678", direction=1, length=8 -> eeprom_list=['78', '56', '34', '12'] |
633 @param data : string to be reconstructed |
633 @param data : string to be reconstructed |
634 @param direction : endianness |
634 @param direction : endianness |
635 @param length : data length |
635 @param length : data length |
636 @return eeprom_list : reconstructed list data structure |
636 @return eeprom_list : reconstructed list data structure |
637 """ |
637 """ |
638 eeprom_list = [] |
638 eeprom_list = [] |
639 |
639 |
640 if direction is 0 or 1: |
640 if direction is 0 or 1: |
641 for i in range(length/2): |
641 for i in range(length/2): |
642 if data == "": |
642 if data == "": |
644 else: |
644 else: |
645 eeprom_list.append(data[direction*(length-2):direction*(length-2)+2]) |
645 eeprom_list.append(data[direction*(length-2):direction*(length-2)+2]) |
646 data = data[(1-direction)*2:length-direction*2] |
646 data = data[(1-direction)*2:length-direction*2] |
647 length -= 2 |
647 length -= 2 |
648 return eeprom_list |
648 return eeprom_list |
649 |
649 |
650 def XmlToEeprom(self): |
650 def XmlToEeprom(self): |
651 """ |
651 """ |
652 Extract slave EEPROM contents using slave ESI XML file. |
652 Extract slave EEPROM contents using slave ESI XML file. |
653 - Mandatory parts |
653 - Mandatory parts |
654 - String category : ExtractEEPROMStringCategory() |
654 - String category : ExtractEEPROMStringCategory() |
655 - General category : ExtractEEPROMGeneralCategory() |
655 - General category : ExtractEEPROMGeneralCategory() |
656 - FMMU category : ExtractEEPROMFMMUCategory |
656 - FMMU category : ExtractEEPROMFMMUCategory |
657 - SyncM category : ExtractEEPROMSyncMCategory() |
657 - SyncM category : ExtractEEPROMSyncMCategory() |
658 - Tx/RxPDO category : ExtractEEPROMPDOCategory() |
658 - Tx/RxPDO category : ExtractEEPROMPDOCategory() |
659 - DC category : ExtractEEPROMDCCategory() |
659 - DC category : ExtractEEPROMDCCategory() |
660 @return eeprom_binary |
660 @return eeprom_binary |
661 """ |
661 """ |
662 eeprom = [] |
662 eeprom = [] |
663 data = "" |
663 data = "" |
664 eeprom_size = 0 |
664 eeprom_size = 0 |
665 eeprom_binary = "" |
665 eeprom_binary = "" |
666 |
666 |
667 # 'device' is the slave device of the current EtherCAT slave plugin |
667 # 'device' is the slave device of the current EtherCAT slave plugin |
668 slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) |
668 slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) |
669 type_infos = slave.getType() |
669 type_infos = slave.getType() |
670 device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) |
670 device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) |
671 |
671 |
672 if device is not None: |
672 if device is not None: |
673 # get ConfigData for EEPROM offset 0x0000-0x000d; <Device>-<Eeprom>-<ConfigData> |
673 # get ConfigData for EEPROM offset 0x0000-0x000d; <Device>-<Eeprom>-<ConfigData> |
674 for eeprom_element in device.getEeprom().getcontent(): |
674 for eeprom_element in device.getEeprom().getcontent(): |
675 if eeprom_element["name"] == "ConfigData": |
675 if eeprom_element["name"] == "ConfigData": |
676 data = self.DecimalToHex(eeprom_element) |
676 data = self.DecimalToHex(eeprom_element) |
677 eeprom += self.GenerateEEPROMList(data, 0, 28) |
677 eeprom += self.GenerateEEPROMList(data, 0, 28) |
678 |
678 |
679 # calculate CRC for EEPROM offset 0x000e-0x000f |
679 # calculate CRC for EEPROM offset 0x000e-0x000f |
680 crc = 0x48 |
680 crc = 0x48 |
681 for segment in eeprom: |
681 for segment in eeprom: |
682 for i in range(8): |
682 for i in range(8): |
683 bit = crc & 0x80 |
683 bit = crc & 0x80 |
684 crc = (crc << 1) | ((int(segment, 16) >> (7 - i)) & 0x01) |
684 crc = (crc << 1) | ((int(segment, 16) >> (7 - i)) & 0x01) |
685 if bit: |
685 if bit: |
686 crc ^= 0x07 |
686 crc ^= 0x07 |
687 for k in range(8): |
687 for k in range(8): |
688 bit = crc & 0x80 |
688 bit = crc & 0x80 |
689 crc <<= 1 |
689 crc <<= 1 |
690 if bit: |
690 if bit: |
691 crc ^= 0x07 |
691 crc ^= 0x07 |
692 eeprom.append(hex(crc)[len(hex(crc))-3:len(hex(crc))-1]) |
692 eeprom.append(hex(crc)[len(hex(crc))-3:len(hex(crc))-1]) |
693 eeprom.append("00") |
693 eeprom.append("00") |
694 |
694 |
695 # get VendorID for EEPROM offset 0x0010-0x0013; |
695 # get VendorID for EEPROM offset 0x0010-0x0013; |
696 data = "" |
696 data = "" |
697 for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): |
697 for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): |
698 for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]: |
698 for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]: |
699 if available_device[0] == type_infos["device_type"]: |
699 if available_device[0] == type_infos["device_type"]: |
700 data = "{:0>8x}".format(vendor_id) |
700 data = "{:0>8x}".format(vendor_id) |
701 eeprom += self.GenerateEEPROMList(data, 1, 8) |
701 eeprom += self.GenerateEEPROMList(data, 1, 8) |
702 |
702 |
703 # get Product Code for EEPROM offset 0x0014-0x0017; |
703 # get Product Code for EEPROM offset 0x0014-0x0017; |
704 data = "" |
704 data = "" |
705 if device.getType().getProductCode() is not None: |
705 if device.getType().getProductCode() is not None: |
706 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getProductCode())) |
706 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getProductCode())) |
707 eeprom += self.GenerateEEPROMList(data, 1, 8) |
707 eeprom += self.GenerateEEPROMList(data, 1, 8) |
708 |
708 |
709 # get Revision Number for EEPROM offset 0x0018-0x001b; |
709 # get Revision Number for EEPROM offset 0x0018-0x001b; |
710 data = "" |
710 data = "" |
711 if device.getType().getRevisionNo() is not None: |
711 if device.getType().getRevisionNo() is not None: |
712 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getRevisionNo())) |
712 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getRevisionNo())) |
713 eeprom += self.GenerateEEPROMList(data, 1, 8) |
713 eeprom += self.GenerateEEPROMList(data, 1, 8) |
714 |
714 |
715 # get Serial Number for EEPROM 0x001c-0x001f; |
715 # get Serial Number for EEPROM 0x001c-0x001f; |
716 data = "" |
716 data = "" |
717 if device.getType().getSerialNo() is not None: |
717 if device.getType().getSerialNo() is not None: |
718 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getSerialNo())) |
718 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getSerialNo())) |
719 eeprom += self.GenerateEEPROMList(data, 1, 8) |
719 eeprom += self.GenerateEEPROMList(data, 1, 8) |
720 |
720 |
721 # get Execution Delay for EEPROM 0x0020-0x0021; not analyzed yet |
721 # get Execution Delay for EEPROM 0x0020-0x0021; not analyzed yet |
722 eeprom.append("00") |
722 eeprom.append("00") |
723 eeprom.append("00") |
723 eeprom.append("00") |
724 |
724 |
725 # get Port0/1 Delay for EEPROM offset 0x0022-0x0025; not analyzed yet |
725 # get Port0/1 Delay for EEPROM offset 0x0022-0x0025; not analyzed yet |
726 eeprom.append("00") |
726 eeprom.append("00") |
727 eeprom.append("00") |
727 eeprom.append("00") |
728 eeprom.append("00") |
728 eeprom.append("00") |
729 eeprom.append("00") |
729 eeprom.append("00") |
730 |
730 |
731 # reserved for EEPROM offset 0x0026-0x0027; |
731 # reserved for EEPROM offset 0x0026-0x0027; |
732 eeprom.append("00") |
732 eeprom.append("00") |
733 eeprom.append("00") |
733 eeprom.append("00") |
734 |
734 |
735 # get BootStrap for EEPROM offset 0x0028-0x002e; <Device>-<Eeprom>-<BootStrap> |
735 # get BootStrap for EEPROM offset 0x0028-0x002e; <Device>-<Eeprom>-<BootStrap> |
736 data = "" |
736 data = "" |
737 for eeprom_element in device.getEeprom().getcontent(): |
737 for eeprom_element in device.getEeprom().getcontent(): |
738 if eeprom_element["name"] == "BootStrap": |
738 if eeprom_element["name"] == "BootStrap": |
739 data = "{:0>16x}".format(eeprom_element) |
739 data = "{:0>16x}".format(eeprom_element) |
740 eeprom += self.GenerateEEPROMList(data, 0, 16) |
740 eeprom += self.GenerateEEPROMList(data, 0, 16) |
741 |
741 |
742 # get Standard Mailbox for EEPROM offset 0x0030-0x0037; <Device>-<sm> |
742 # get Standard Mailbox for EEPROM offset 0x0030-0x0037; <Device>-<sm> |
743 data = "" |
743 data = "" |
744 standard_send_mailbox_offset = None |
744 standard_send_mailbox_offset = None |
745 standard_send_mailbox_size = None |
745 standard_send_mailbox_size = None |
746 standard_receive_mailbox_offset = None |
746 standard_receive_mailbox_offset = None |
804 eeprom.append("00") |
804 eeprom.append("00") |
805 eeprom.append("00") |
805 eeprom.append("00") |
806 else: |
806 else: |
807 eeprom.append(data[2:4]) |
807 eeprom.append(data[2:4]) |
808 eeprom.append(data[0:2]) |
808 eeprom.append(data[0:2]) |
809 |
809 |
810 # Version for EEPROM 0x007e-0x007f; |
810 # Version for EEPROM 0x007e-0x007f; |
811 # According to "EtherCAT Slave Device Description(V0.3.0)" |
811 # According to "EtherCAT Slave Device Description(V0.3.0)" |
812 eeprom.append("01") |
812 eeprom.append("01") |
813 eeprom.append("00") |
813 eeprom.append("00") |
814 |
814 |
815 # append String Category data |
815 # append String Category data |
816 for data in self.ExtractEEPROMStringCategory(device): |
816 for data in self.ExtractEEPROMStringCategory(device): |
817 eeprom.append(data) |
817 eeprom.append(data) |
818 |
818 |
819 # append General Category data |
819 # append General Category data |
820 for data in self.ExtractEEPROMGeneralCategory(device): |
820 for data in self.ExtractEEPROMGeneralCategory(device): |
821 eeprom.append(data) |
821 eeprom.append(data) |
822 |
822 |
823 # append FMMU Category data |
823 # append FMMU Category data |
824 for data in self.ExtractEEPROMFMMUCategory(device): |
824 for data in self.ExtractEEPROMFMMUCategory(device): |
825 eeprom.append(data) |
825 eeprom.append(data) |
826 |
826 |
827 # append SyncM Category data |
827 # append SyncM Category data |
828 for data in self.ExtractEEPROMSyncMCategory(device): |
828 for data in self.ExtractEEPROMSyncMCategory(device): |
829 eeprom.append(data) |
829 eeprom.append(data) |
830 |
830 |
831 # append TxPDO Category data |
831 # append TxPDO Category data |
832 for data in self.ExtractEEPROMPDOCategory(device, "TxPdo"): |
832 for data in self.ExtractEEPROMPDOCategory(device, "TxPdo"): |
833 eeprom.append(data) |
833 eeprom.append(data) |
834 |
834 |
835 # append RxPDO Category data |
835 # append RxPDO Category data |
836 for data in self.ExtractEEPROMPDOCategory(device, "RxPdo"): |
836 for data in self.ExtractEEPROMPDOCategory(device, "RxPdo"): |
837 eeprom.append(data) |
837 eeprom.append(data) |
838 |
838 |
839 # append DC Category data |
839 # append DC Category data |
840 for data in self.ExtractEEPROMDCCategory(device): |
840 for data in self.ExtractEEPROMDCCategory(device): |
841 eeprom.append(data) |
841 eeprom.append(data) |
842 |
842 |
843 # append padding |
843 # append padding |
844 padding = eeprom_size-len(eeprom) |
844 padding = eeprom_size-len(eeprom) |
845 for i in range(padding): |
845 for i in range(padding): |
846 eeprom.append("ff") |
846 eeprom.append("ff") |
847 |
847 |
848 # convert binary code |
848 # convert binary code |
849 for index in range(eeprom_size): |
849 for index in range(eeprom_size): |
850 eeprom_binary = eeprom_binary + eeprom[index].decode('hex') |
850 eeprom_binary = eeprom_binary + eeprom[index].decode('hex') |
851 |
851 |
852 return eeprom_binary |
852 return eeprom_binary |
853 |
853 |
854 def ExtractEEPROMStringCategory(self, device): |
854 def ExtractEEPROMStringCategory(self, device): |
855 """ |
855 """ |
856 Extract "Strings" category data from slave ESI XML and generate EEPROM image data. |
856 Extract "Strings" category data from slave ESI XML and generate EEPROM image data. |
857 @param device : 'device' object in the slave ESI XML |
857 @param device : 'device' object in the slave ESI XML |
858 @return eeprom : "Strings" category EEPROM image data |
858 @return eeprom : "Strings" category EEPROM image data |
859 """ |
859 """ |
860 eeprom = [] |
860 eeprom = [] |
861 self.Strings = [] |
861 self.Strings = [] |
862 data = "" |
862 data = "" |
863 count = 0 # string counter |
863 count = 0 # string counter |
864 padflag = False # padding flag if category length is odd |
864 padflag = False # padding flag if category length is odd |
865 |
865 |
866 # index information for General Category in EEPROM |
866 # index information for General Category in EEPROM |
867 self.GroupIdx = 0 |
867 self.GroupIdx = 0 |
868 self.ImgIdx = 0 |
868 self.ImgIdx = 0 |
869 self.OrderIdx = 0 |
869 self.OrderIdx = 0 |
870 self.NameIdx = 0 |
870 self.NameIdx = 0 |
871 |
871 |
872 # flag for preventing duplicated vendor specific data |
872 # flag for preventing duplicated vendor specific data |
873 typeflag = False |
873 typeflag = False |
874 grouptypeflag = False |
874 grouptypeflag = False |
875 groupnameflag = False |
875 groupnameflag = False |
876 devnameflag = False |
876 devnameflag = False |
877 imageflag = False |
877 imageflag = False |
878 |
878 |
879 # vendor specific data |
879 # vendor specific data |
880 # element1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Type> |
880 # element1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Type> |
881 # vendor_specific_data : vendor specific data (binary type) |
881 # vendor_specific_data : vendor specific data (binary type) |
882 vendor_specific_data = "" |
882 vendor_specific_data = "" |
883 # vendor_spec_strings : list of vendor specific "strings" for preventing duplicated strings |
883 # vendor_spec_strings : list of vendor specific "strings" for preventing duplicated strings |
884 vendor_spec_strings = [] |
884 vendor_spec_strings = [] |
885 for element in device.getType().getcontent(): |
885 for element in device.getType().getcontent(): |
886 data += element |
886 data += element |
887 if data is not "" and type(data) == unicode: |
887 if data is not "" and type(data) == unicode: |
888 for vendor_spec_string in vendor_spec_strings: |
888 for vendor_spec_string in vendor_spec_strings: |
889 if data == vendor_spec_string: |
889 if data == vendor_spec_string: |
890 self.OrderIdx = vendor_spec_strings.index(data)+1 |
890 self.OrderIdx = vendor_spec_strings.index(data)+1 |
891 typeflag = True |
891 typeflag = True |
892 break |
892 break |
893 if typeflag is False: |
893 if typeflag is False: |
1044 self.Strings.append(data) |
1044 self.Strings.append(data) |
1045 dc_related_elements += "{:0>2x}".format(len(data)) |
1045 dc_related_elements += "{:0>2x}".format(len(data)) |
1046 for character in range(len(data)): |
1046 for character in range(len(data)): |
1047 dc_related_elements += "{:0>2x}".format(ord(data[character])) |
1047 dc_related_elements += "{:0>2x}".format(ord(data[character])) |
1048 data = "" |
1048 data = "" |
1049 |
1049 |
1050 # Input elements(TxPDO) |
1050 # Input elements(TxPDO) |
1051 # <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<TxPdo>; Name |
1051 # <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<TxPdo>; Name |
1052 input_elements = "" |
1052 input_elements = "" |
1053 inputs = [] |
1053 inputs = [] |
1054 for element in device.getTxPdo(): |
1054 for element in device.getTxPdo(): |
1055 for name in element.getName(): |
1055 for name in element.getName(): |
1056 data = name.getcontent() |
1056 data = name.getcontent() |
1057 for input in inputs: |
1057 for input in inputs: |
1058 if data == input: |
1058 if data == input: |
1059 data = "" |
1059 data = "" |
1060 if data is not "": |
1060 if data is not "": |
1061 count += 1 |
1061 count += 1 |
1062 self.Strings.append(data) |
1062 self.Strings.append(data) |
1063 inputs.append(data) |
1063 inputs.append(data) |
1064 input_elements += "{:0>2x}".format(len(data)) |
1064 input_elements += "{:0>2x}".format(len(data)) |
1065 for character in range(len(data)): |
1065 for character in range(len(data)): |
1066 input_elements += "{:0>2x}".format(ord(data[character])) |
1066 input_elements += "{:0>2x}".format(ord(data[character])) |
1067 data = "" |
1067 data = "" |
1068 for entry in element.getEntry(): |
1068 for entry in element.getEntry(): |
1069 for name in entry.getName(): |
1069 for name in entry.getName(): |
1070 data = name.getcontent() |
1070 data = name.getcontent() |
1071 for input in inputs: |
1071 for input in inputs: |
1072 if data == input: |
1072 if data == input: |
1073 data = "" |
1073 data = "" |
1074 if data is not "": |
1074 if data is not "": |
1075 count += 1 |
1075 count += 1 |
1076 self.Strings.append(data) |
1076 self.Strings.append(data) |
1077 inputs.append(data) |
1077 inputs.append(data) |
1078 input_elements += "{:0>2x}".format(len(data)) |
1078 input_elements += "{:0>2x}".format(len(data)) |
1079 for character in range(len(data)): |
1079 for character in range(len(data)): |
1080 input_elements += "{:0>2x}".format(ord(data[character])) |
1080 input_elements += "{:0>2x}".format(ord(data[character])) |
1081 data = "" |
1081 data = "" |
1082 |
1082 |
1083 # Output elements(RxPDO) |
1083 # Output elements(RxPDO) |
1084 # <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<RxPdo>; Name |
1084 # <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<RxPdo>; Name |
1085 output_elements = "" |
1085 output_elements = "" |
1086 outputs = [] |
1086 outputs = [] |
1087 for element in device.getRxPdo(): |
1087 for element in device.getRxPdo(): |
1088 for name in element.getName(): |
1088 for name in element.getName(): |
1089 data = name.getcontent() |
1089 data = name.getcontent() |
1090 for output in outputs: |
1090 for output in outputs: |
1091 if data == output: |
1091 if data == output: |
1092 data = "" |
1092 data = "" |
1093 if data is not "": |
1093 if data is not "": |
1094 count += 1 |
1094 count += 1 |
1095 self.Strings.append(data) |
1095 self.Strings.append(data) |
1096 outputs.append(data) |
1096 outputs.append(data) |
1097 output_elements += "{:0>2x}".format(len(data)) |
1097 output_elements += "{:0>2x}".format(len(data)) |
1098 for character in range(len(data)): |
1098 for character in range(len(data)): |
1099 output_elements += "{:0>2x}".format(ord(data[character])) |
1099 output_elements += "{:0>2x}".format(ord(data[character])) |
1100 data = "" |
1100 data = "" |
1101 for entry in element.getEntry(): |
1101 for entry in element.getEntry(): |
1102 for name in entry.getName(): |
1102 for name in entry.getName(): |
1103 data = name.getcontent() |
1103 data = name.getcontent() |
1104 for output in outputs: |
1104 for output in outputs: |
1105 if data == output: |
1105 if data == output: |
1106 data = "" |
1106 data = "" |
1107 if data is not "": |
1107 if data is not "": |
1108 count += 1 |
1108 count += 1 |
1109 self.Strings.append(data) |
1109 self.Strings.append(data) |
1110 outputs.append(data) |
1110 outputs.append(data) |
1111 output_elements += "{:0>2x}".format(len(data)) |
1111 output_elements += "{:0>2x}".format(len(data)) |
1112 for character in range(len(data)): |
1112 for character in range(len(data)): |
1113 output_elements += "{:0>2x}".format(ord(data[character])) |
1113 output_elements += "{:0>2x}".format(ord(data[character])) |
1114 data = "" |
1114 data = "" |
1115 |
1115 |
1116 # form eeprom data |
1116 # form eeprom data |
1117 # category header |
1117 # category header |
1118 eeprom.append("0a") |
1118 eeprom.append("0a") |
1119 eeprom.append("00") |
1119 eeprom.append("00") |
1120 # category length (word); 1 word is 4 bytes. "+2" is the length of string's total number |
1120 # category length (word); 1 word is 4 bytes. "+2" is the length of string's total number |
1135 for iter in range(len(element)/2): |
1135 for iter in range(len(element)/2): |
1136 if element == "": |
1136 if element == "": |
1137 eeprom.append("00") |
1137 eeprom.append("00") |
1138 else: |
1138 else: |
1139 eeprom.append(element[0:2]) |
1139 eeprom.append(element[0:2]) |
1140 element = element[2:len(element)] |
1140 element = element[2:len(element)] |
1141 # padding if length is odd bytes |
1141 # padding if length is odd bytes |
1142 if padflag is True: |
1142 if padflag is True: |
1143 eeprom.append("ff") |
1143 eeprom.append("ff") |
1144 |
1144 |
1145 return eeprom |
1145 return eeprom |
1146 |
1146 |
1147 def ExtractEEPROMGeneralCategory(self, device): |
1147 def ExtractEEPROMGeneralCategory(self, device): |
1148 """ |
1148 """ |
1149 Extract "General" category data from slave ESI XML and generate EEPROM image data. |
1149 Extract "General" category data from slave ESI XML and generate EEPROM image data. |
1150 @param device : 'device' object in the slave ESI XML |
1150 @param device : 'device' object in the slave ESI XML |
1151 @return eeprom : "Strings" category EEPROM image data |
1151 @return eeprom : "Strings" category EEPROM image data |
1152 """ |
1152 """ |
1153 eeprom = [] |
1153 eeprom = [] |
1154 data = "" |
1154 data = "" |
1155 |
1155 |
1156 # category header |
1156 # category header |
1157 eeprom.append("1e") |
1157 eeprom.append("1e") |
1158 eeprom.append("00") |
1158 eeprom.append("00") |
1159 |
1159 |
1160 # category length |
1160 # category length |
1161 eeprom.append("10") |
1161 eeprom.append("10") |
1162 eeprom.append("00") |
1162 eeprom.append("00") |
1163 |
1163 |
1164 # word 1 : Group Type index and Image index in STRINGS Category |
1164 # word 1 : Group Type index and Image index in STRINGS Category |
1165 eeprom.append("{:0>2x}".format(self.GroupIdx)) |
1165 eeprom.append("{:0>2x}".format(self.GroupIdx)) |
1166 eeprom.append("{:0>2x}".format(self.ImgIdx)) |
1166 eeprom.append("{:0>2x}".format(self.ImgIdx)) |
1167 |
1167 |
1168 # word 2 : Device Type index and Device Name index in STRINGS Category |
1168 # word 2 : Device Type index and Device Name index in STRINGS Category |
1169 eeprom.append("{:0>2x}".format(self.OrderIdx)) |
1169 eeprom.append("{:0>2x}".format(self.OrderIdx)) |
1170 eeprom.append("{:0>2x}".format(self.NameIdx)) |
1170 eeprom.append("{:0>2x}".format(self.NameIdx)) |
1171 |
1171 |
1172 # word 3 : Physical Layer Port info. and CoE Details |
1172 # word 3 : Physical Layer Port info. and CoE Details |
1173 eeprom.append("01") # Physical Layer Port info - assume 01 |
1173 eeprom.append("01") # Physical Layer Port info - assume 01 |
1174 # CoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<CoE> |
1174 # CoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<CoE> |
1175 coe_details = 0 |
1175 coe_details = 0 |
1176 mb = device.getMailbox() |
1176 mb = device.getMailbox() |
1177 coe_details = 1 # sdo enabled |
1177 coe_details = 1 # sdo enabled |
1178 if mb is not None : |
1178 if mb is not None : |
1179 coe = mb.getCoE() |
1179 coe = mb.getCoE() |
1180 if coe is not None: |
1180 if coe is not None: |
1181 for bit,flag in enumerate(["SdoInfo", "PdoAssign", "PdoConfig", |
1181 for bit,flag in enumerate(["SdoInfo", "PdoAssign", "PdoConfig", |
1182 "PdoUpload", "CompleteAccess"]): |
1182 "PdoUpload", "CompleteAccess"]): |
1183 if getattr(coe,"get%s"%flag)() is not None: |
1183 if getattr(coe,"get%s"%flag)() is not None: |
1184 coe_details += 1<<bit |
1184 coe_details += 1<<bit |
1185 eeprom.append("{:0>2x}".format(coe_details)) |
1185 eeprom.append("{:0>2x}".format(coe_details)) |
1186 |
1186 |
1187 # word 4 : FoE Details and EoE Details |
1187 # word 4 : FoE Details and EoE Details |
1188 # FoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<FoE> |
1188 # FoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<FoE> |
1189 if mb is not None and mb.getFoE() is not None: |
1189 if mb is not None and mb.getFoE() is not None: |
1190 eeprom.append("01") |
1190 eeprom.append("01") |
1191 else: |
1191 else: |
1245 eeprom.append("00") |
1245 eeprom.append("00") |
1246 eeprom.append("00") |
1246 eeprom.append("00") |
1247 eeprom.append("00") |
1247 eeprom.append("00") |
1248 eeprom.append("00") |
1248 eeprom.append("00") |
1249 eeprom.append("00") |
1249 eeprom.append("00") |
1250 |
1250 |
1251 return eeprom |
1251 return eeprom |
1252 |
1252 |
1253 def ExtractEEPROMFMMUCategory(self, device): |
1253 def ExtractEEPROMFMMUCategory(self, device): |
1254 """ |
1254 """ |
1255 Extract "FMMU" category data from slave ESI XML and generate EEPROM image data. |
1255 Extract "FMMU" category data from slave ESI XML and generate EEPROM image data. |
1256 @param device : 'device' object in the slave ESI XML |
1256 @param device : 'device' object in the slave ESI XML |
1257 @return eeprom : "Strings" category EEPROM image data |
1257 @return eeprom : "Strings" category EEPROM image data |
1258 """ |
1258 """ |
1259 eeprom = [] |
1259 eeprom = [] |
1260 data = "" |
1260 data = "" |
1261 count = 0 # number of FMMU |
1261 count = 0 # number of FMMU |
1262 padflag = False |
1262 padflag = False |
1263 |
1263 |
1264 for fmmu in device.getFmmu(): |
1264 for fmmu in device.getFmmu(): |
1265 count += 1 |
1265 count += 1 |
1266 if fmmu.getcontent() == "Outputs": |
1266 if fmmu.getcontent() == "Outputs": |
1267 data += "01" |
1267 data += "01" |
1268 if fmmu.getcontent() == "Inputs": |
1268 if fmmu.getcontent() == "Inputs": |
1269 data += "02" |
1269 data += "02" |
1270 if fmmu.getcontent() == "MBoxState": |
1270 if fmmu.getcontent() == "MBoxState": |
1271 data += "03" |
1271 data += "03" |
1272 |
1272 |
1273 # construct of EEPROM data |
1273 # construct of EEPROM data |
1274 if data is not "": |
1274 if data is not "": |
1275 # category header |
1275 # category header |
1276 eeprom.append("28") |
1276 eeprom.append("28") |
1277 eeprom.append("00") |
1277 eeprom.append("00") |
1278 # category length |
1278 # category length |
1279 if count%2 == 1: |
1279 if count%2 == 1: |
1280 padflag = True |
1280 padflag = True |
1281 eeprom.append("{:0>4x}".format((count+1)/2)[2:4]) |
1281 eeprom.append("{:0>4x}".format((count+1)/2)[2:4]) |
1282 eeprom.append("{:0>4x}".format((count+1)/2)[0:2]) |
1282 eeprom.append("{:0>4x}".format((count+1)/2)[0:2]) |
1283 else: |
1283 else: |
1284 eeprom.append("{:0>4x}".format((count)/2)[2:4]) |
1284 eeprom.append("{:0>4x}".format((count)/2)[2:4]) |
1285 eeprom.append("{:0>4x}".format((count)/2)[0:2]) |
1285 eeprom.append("{:0>4x}".format((count)/2)[0:2]) |
1286 for i in range(count): |
1286 for i in range(count): |
1287 if data == "": |
1287 if data == "": |
1288 eeprom.append("00") |
1288 eeprom.append("00") |
1289 else: |
1289 else: |
1290 eeprom.append(data[0:2]) |
1290 eeprom.append(data[0:2]) |
1291 data = data[2:len(data)] |
1291 data = data[2:len(data)] |
1292 # padding if length is odd bytes |
1292 # padding if length is odd bytes |
1293 if padflag is True: |
1293 if padflag is True: |
1294 eeprom.append("ff") |
1294 eeprom.append("ff") |
1295 |
1295 |
1296 return eeprom |
1296 return eeprom |
1297 |
1297 |
1298 def ExtractEEPROMSyncMCategory(self, device): |
1298 def ExtractEEPROMSyncMCategory(self, device): |
1299 """ |
1299 """ |
1300 Extract "SyncM" category data from slave ESI XML and generate EEPROM image data. |
1300 Extract "SyncM" category data from slave ESI XML and generate EEPROM image data. |
1301 @param device : 'device' object in the slave ESI XML |
1301 @param device : 'device' object in the slave ESI XML |
1302 @return eeprom : "Strings" category EEPROM image data |
1302 @return eeprom : "Strings" category EEPROM image data |
1303 """ |
1303 """ |
1304 eeprom = [] |
1304 eeprom = [] |
1305 data = "" |
1305 data = "" |
1306 number = {"MBoxOut":"01", "MBoxIn":"02", "Outputs":"03", "Inputs":"04"} |
1306 number = {"MBoxOut":"01", "MBoxIn":"02", "Outputs":"03", "Inputs":"04"} |
1307 |
1307 |
1308 for sm in device.getSm(): |
1308 for sm in device.getSm(): |
1309 for attr in [sm.getStartAddress(), |
1309 for attr in [sm.getStartAddress(), |
1310 sm.getDefaultSize(), |
1310 sm.getDefaultSize(), |
1311 sm.getControlByte()]: |
1311 sm.getControlByte()]: |
1312 if attr is not None: |
1312 if attr is not None: |
1313 data += "{:0>4x}".format(ExtractHexDecValue(attr))[2:4] |
1313 data += "{:0>4x}".format(ExtractHexDecValue(attr))[2:4] |
1314 data += "{:0>4x}".format(ExtractHexDecValue(attr))[0:2] |
1314 data += "{:0>4x}".format(ExtractHexDecValue(attr))[0:2] |
1315 else: |
1315 else: |
1316 data += "0000" |
1316 data += "0000" |
1317 if sm.getEnable() == "1" or sm.getEnable() == True: |
1317 if sm.getEnable() == "1" or sm.getEnable() == True: |
1318 data += "01" |
1318 data += "01" |
1319 else: |
1319 else: |
1320 data += "00" |
1320 data += "00" |
1321 data += number[sm.getcontent()] |
1321 data += number[sm.getcontent()] |
1322 |
1322 |
1323 if data is not "": |
1323 if data is not "": |
1324 # category header |
1324 # category header |
1325 eeprom.append("29") |
1325 eeprom.append("29") |
1326 eeprom.append("00") |
1326 eeprom.append("00") |
1327 # category length |
1327 # category length |
1328 eeprom.append("{:0>4x}".format(len(data)/4)[2:4]) |
1328 eeprom.append("{:0>4x}".format(len(data)/4)[2:4]) |
1329 eeprom.append("{:0>4x}".format(len(data)/4)[0:2]) |
1329 eeprom.append("{:0>4x}".format(len(data)/4)[0:2]) |
1330 for i in range(len(data)/2): |
1330 for i in range(len(data)/2): |
1331 if data == "": |
1331 if data == "": |
1332 eeprom.append("00") |
1332 eeprom.append("00") |
1333 else: |
1333 else: |
1334 eeprom.append(data[0:2]) |
1334 eeprom.append(data[0:2]) |
1335 data = data[2:len(data)] |
1335 data = data[2:len(data)] |
1336 |
1336 |
1337 return eeprom |
1337 return eeprom |
1338 |
1338 |
1339 def ExtractEEPROMPDOCategory(self, device, pdotype): |
1339 def ExtractEEPROMPDOCategory(self, device, pdotype): |
1340 """ |
1340 """ |
1341 Extract ""PDO (Tx, Rx)"" category data from slave ESI XML and generate EEPROM image data. |
1341 Extract ""PDO (Tx, Rx)"" category data from slave ESI XML and generate EEPROM image data. |
1342 @param device : 'device' object in the slave ESI XML |
1342 @param device : 'device' object in the slave ESI XML |
1343 @param pdotype : identifier whether "TxPDO" or "RxPDO". |
1343 @param pdotype : identifier whether "TxPDO" or "RxPDO". |
1344 @return eeprom : "Strings" category EEPROM image data |
1344 @return eeprom : "Strings" category EEPROM image data |
1345 """ |
1345 """ |
1346 eeprom = [] |
1346 eeprom = [] |
1347 data = "" |
1347 data = "" |
1348 count = 0 |
1348 count = 0 |
1349 en_fixed = False |
1349 en_fixed = False |
1350 en_mandatory = False |
1350 en_mandatory = False |
1351 en_virtual = False |
1351 en_virtual = False |
1352 |
1352 |
1353 for element in eval("device.get%s()"%pdotype): |
1353 for element in eval("device.get%s()"%pdotype): |
1354 # PDO Index |
1354 # PDO Index |
1355 data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[2:4] |
1355 data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[2:4] |
1356 data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[0:2] |
1356 data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[0:2] |
1357 # Number of Entries |
1357 # Number of Entries |
1499 namecount = 0 |
1499 namecount = 0 |
1500 data += "00" |
1500 data += "00" |
1501 # assume that word 11-12 are 0x0000 |
1501 # assume that word 11-12 are 0x0000 |
1502 data += "0000" |
1502 data += "0000" |
1503 data += "0000" |
1503 data += "0000" |
1504 |
1504 |
1505 if data is not "": |
1505 if data is not "": |
1506 # category header |
1506 # category header |
1507 eeprom.append("3c") |
1507 eeprom.append("3c") |
1508 eeprom.append("00") |
1508 eeprom.append("00") |
1509 # category length |
1509 # category length |
1510 eeprom.append("{:0>4x}".format(len(data)/4)[2:4]) |
1510 eeprom.append("{:0>4x}".format(len(data)/4)[2:4]) |
1511 eeprom.append("{:0>4x}".format(len(data)/4)[0:2]) |
1511 eeprom.append("{:0>4x}".format(len(data)/4)[0:2]) |
1512 data = str(data.lower()) |
1512 data = str(data.lower()) |
1513 for i in range(len(data)/2): |
1513 for i in range(len(data)/2): |
1514 if data == "": |
1514 if data == "": |
1515 eeprom.append("00") |
1515 eeprom.append("00") |
1516 else: |
1516 else: |
1517 eeprom.append(data[0:2]) |
1517 eeprom.append(data[0:2]) |
1518 data = data[2:len(data)] |
1518 data = data[2:len(data)] |
1519 |
1519 |
1520 return eeprom |
1520 return eeprom |
1521 |
1521 |
1522 #------------------------------------------------------------------------------- |
1522 #------------------------------------------------------------------------------- |
1523 # Used Register Access |
1523 # Used Register Access |
1524 #------------------------------------------------------------------------------- |
1524 #------------------------------------------------------------------------------- |
1525 def RegRead(self, offset, length): |
1525 def RegRead(self, offset, length): |
1526 """ |
1526 """ |
1527 Read slave ESC register content using "ethercat reg_read -p %d %s %s" command. |
1527 Read slave ESC register content using "ethercat reg_read -p %d %s %s" command. |
1528 Command example : "ethercat reg_read -p 0 0x0c00 0x0400" |
1528 Command example : "ethercat reg_read -p 0 0x0c00 0x0400" |
1529 @param offset : register address |
1529 @param offset : register address |
1530 @param length : register length |
1530 @param length : register length |
1531 @return return_val : register data |
1531 @return return_val : register data |
1532 """ |
1532 """ |
1533 error, return_val = self.Controler.RemoteExec(REG_READ%(self.Controler.GetSlavePos(), offset, length), return_val = None) |
1533 error, return_val = self.Controler.RemoteExec(REG_READ%(self.Controler.GetSlavePos(), offset, length), return_val = None) |
1534 return return_val |
1534 return return_val |
1535 |
1535 |
1536 def RegWrite(self, address, data): |
1536 def RegWrite(self, address, data): |
1537 """ |
1537 """ |
1538 Write data to slave ESC register using "ethercat reg_write -p %d %s %s" command. |
1538 Write data to slave ESC register using "ethercat reg_write -p %d %s %s" command. |
1539 Command example : "ethercat reg_write -p 0 0x0c04 0x0001" |
1539 Command example : "ethercat reg_write -p 0 0x0c04 0x0001" |
1540 @param address : register address |
1540 @param address : register address |
1541 @param data : data to write |
1541 @param data : data to write |
1542 @return return_val : the execution result of "ethercat reg_write" (for error check) |
1542 @return return_val : the execution result of "ethercat reg_write" (for error check) |
1543 """ |
1543 """ |
1544 error, return_val = self.Controler.RemoteExec(REG_WRITE%(self.Controler.GetSlavePos(), address, data), return_val = None) |
1544 error, return_val = self.Controler.RemoteExec(REG_WRITE%(self.Controler.GetSlavePos(), address, data), return_val = None) |
1545 return return_val |
1545 return return_val |
1546 |
1546 |
1547 def Rescan(self): |
1547 def Rescan(self): |
1548 """ |
1548 """ |
1549 Synchronize EEPROM data in master controller with the data in slave device after EEPROM write. |
1549 Synchronize EEPROM data in master controller with the data in slave device after EEPROM write. |
1550 Command example : "ethercat rescan -p 0" |
1550 Command example : "ethercat rescan -p 0" |
1551 """ |
1551 """ |
1552 error, return_val = self.Controler.RemoteExec(RESCAN%(self.Controler.GetSlavePos()), return_val = None) |
1552 error, return_val = self.Controler.RemoteExec(RESCAN%(self.Controler.GetSlavePos()), return_val = None) |
1553 |
1553 |
1554 #------------------------------------------------------------------------------- |
1554 #------------------------------------------------------------------------------- |
1555 # Common Use Methods |
1555 # Common Use Methods |
1556 #------------------------------------------------------------------------------- |
1556 #------------------------------------------------------------------------------- |
1557 def CheckConnect(self, cyclic_flag): |
1557 def CheckConnect(self, cyclic_flag): |
1558 """ |
1558 """ |
1559 Check connection status (1) between Beremiz and the master (2) between the master and the slave. |
1559 Check connection status (1) between Beremiz and the master (2) between the master and the slave. |
1560 @param cyclic_flag: 0 - one shot, 1 - periodic |
1560 @param cyclic_flag: 0 - one shot, 1 - periodic |
1561 @return True or False |
1561 @return True or False |
1562 """ |
1562 """ |
1563 if self.Controler.GetCTRoot()._connector is not None: |
1563 if self.Controler.GetCTRoot()._connector is not None: |
1564 # Check connection between the master and the slave. |
1564 # Check connection between the master and the slave. |
1565 # Command example : "ethercat xml -p 0" |
1565 # Command example : "ethercat xml -p 0" |
1566 error, return_val = self.Controler.RemoteExec(SLAVE_XML%(self.Controler.GetSlavePos()), return_val = None) |
1566 error, return_val = self.Controler.RemoteExec(SLAVE_XML%(self.Controler.GetSlavePos()), return_val = None) |
1567 number_of_lines = return_val.split("\n") |
1567 number_of_lines = return_val.split("\n") |
1568 if len(number_of_lines) <= 2 : # No slave connected to the master controller |
1568 if len(number_of_lines) <= 2 : # No slave connected to the master controller |
1569 if not cyclic_flag : |
1569 if not cyclic_flag : |
1570 self.CreateErrorDialog('No connected slaves') |
1570 self.CreateErrorDialog('No connected slaves') |
1571 return False |
1571 return False |
1572 |
1572 |
1573 elif len(number_of_lines) > 2 : |
1573 elif len(number_of_lines) > 2 : |
1574 return True |
1574 return True |
1575 else: |
1575 else: |
1576 # The master controller is not connected to Beremiz host |
1576 # The master controller is not connected to Beremiz host |
1577 if not cyclic_flag : |
1577 if not cyclic_flag : |
1578 self.CreateErrorDialog('PLC not connected!') |
1578 self.CreateErrorDialog('PLC not connected!') |
1579 return False |
1579 return False |
1580 |
1580 |
1581 def CreateErrorDialog(self, mention): |
1581 def CreateErrorDialog(self, mention): |
1582 """ |
1582 """ |
1583 Create a dialog to indicate error or warning. |
1583 Create a dialog to indicate error or warning. |
1584 @param mention : Error String |
1584 @param mention : Error String |
1585 """ |
1585 """ |
1586 app_frame = self.Controler.GetCTRoot().AppFrame |
1586 app_frame = self.Controler.GetCTRoot().AppFrame |
1587 dlg = wx.MessageDialog (app_frame, mention, |
1587 dlg = wx.MessageDialog (app_frame, mention, |
1588 ' Warning...', |
1588 ' Warning...', |
1589 wx.OK | wx.ICON_INFORMATION) |
1589 wx.OK | wx.ICON_INFORMATION) |
1590 dlg.ShowModal() |
1590 dlg.ShowModal() |
1591 dlg.Destroy() |
1591 dlg.Destroy() |