Edouard@2152: #!/usr/bin/env python Edouard@2152: # -*- coding: utf-8 -*- Edouard@2152: edouard@2165: edouard@2165: # This file is part of Beremiz Edouard@2152: # edouard@2165: # Copyright (C) 2013: Real-Time & Embedded Systems (RTES) Lab. University of Seoul, Korea Edouard@2152: # edouard@2165: # See COPYING file for copyrights details. Edouard@2152: Edouard@2152: import os Edouard@2152: import wx edouard@2641: import re edouard@2641: edouard@2641: from lxml import objectify Edouard@2163: Edouard@2152: def ExtractHexDecValue(value): Edouard@2152: """ Edouard@2152: convert numerical value in string format into decimal or hex format. Edouard@2152: @param value : hex or decimal data Edouard@2152: @return integer data Edouard@2152: """ Edouard@2152: try: Edouard@2152: return int(value) Edouard@2152: except: Edouard@2152: pass Edouard@2152: try: Edouard@2152: return int(value.replace("#", "0"), 16) Edouard@2152: Edouard@2152: except: Edouard@2152: raise ValueError, "Invalid value for HexDecValue \"%s\"" % value Edouard@2152: Edouard@2152: def ExtractName(names, default=None): Edouard@2152: """ Edouard@2152: Extract "name" field from XML entries. Edouard@2152: @param names : XML entry Edouard@2152: @default : if it fails to extract from the designated XML entry, return the default value ("None"). Edouard@2152: @return default or the name extracted Edouard@2152: """ Edouard@2152: if len(names) == 1: Edouard@2152: return names[0].getcontent() Edouard@2152: else: Edouard@2152: for name in names: Edouard@2152: if name.getLcId() == 1033: Edouard@2152: return name.getcontent() Edouard@2152: return default Edouard@2152: Edouard@2152: #-------------------------------------------------- Edouard@2152: # Remote Exec Etherlab Commands Edouard@2152: #-------------------------------------------------- Edouard@2152: Edouard@2152: # --------------------- for master --------------------------- Edouard@2152: MASTER_STATE = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat master") Edouard@2152: returnVal =result Edouard@2152: """ Edouard@2152: Edouard@2152: # --------------------- for slave ---------------------------- Edouard@2152: # ethercat state -p (slave position) (state (INIT, PREOP, SAFEOP, OP)) Edouard@2152: SLAVE_STATE = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat state -p %d %s") Edouard@2152: returnVal = result Edouard@2152: """ Edouard@2152: Edouard@2152: # ethercat slave Edouard@2152: GET_SLAVE = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat slaves") Edouard@2152: returnVal =result Edouard@2152: """ Edouard@2152: Edouard@2152: # ethercat xml -p (slave position) Edouard@2152: SLAVE_XML = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat xml -p %d") Edouard@2152: returnVal = result Edouard@2152: """ Edouard@2152: edouard@2641: # ethercat upload -p (slave position) -t (type) (index) (sub index) edouard@2641: SDO_UPLOAD = """ Edouard@2152: import commands edouard@2641: sdo_data = [] edouard@2641: input_data = "%s" edouard@2641: slave_pos = %d edouard@2641: command_string = "" edouard@2641: for sdo_token in input_data.split(","): edouard@2641: if len(sdo_token) > 1: edouard@2641: sdo_token = sdo_token.strip() edouard@2641: type, idx, subidx = sdo_token.split(" ") edouard@2641: command_string = "ethercat upload -p " + str(slave_pos) + " -t " + type + " " + idx + " " + subidx edouard@2641: result = commands.getoutput(command_string) edouard@2641: sdo_data.append(result) edouard@2641: returnVal =sdo_data Edouard@2152: """ Edouard@2152: Edouard@2152: # ethercat download -p (slave position) (main index) (sub index) (value) Edouard@2152: SDO_DOWNLOAD = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat download --type %s -p %d %s %s %s") Edouard@2152: returnVal =result Edouard@2152: """ Edouard@2152: Edouard@2152: # ethercat sii_read -p (slave position) Edouard@2152: SII_READ = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat sii_read -p %d") Edouard@2152: returnVal =result Edouard@2152: """ Edouard@2152: Edouard@2152: # ethercat reg_read -p (slave position) (address) (size) Edouard@2152: REG_READ = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat reg_read -p %d %s %s") Edouard@2152: returnVal =result Edouard@2152: """ Edouard@2152: edouard@2641: # ethercat reg_read -p (slave position) (address) (size) edouard@2641: MULTI_REG_READ = """ edouard@2641: import commands edouard@2641: output = [] edouard@2641: addr, size = range(2) edouard@2641: slave_num = %d edouard@2641: reg_info_str = "%s" edouard@2641: reg_info_list = reg_info_str.split("|") edouard@2641: for slave_idx in range(slave_num): edouard@2641: for reg_info in reg_info_list: edouard@2641: param = reg_info.split(",") edouard@2641: result = commands.getoutput("ethercat reg_read -p " edouard@2641: + str(slave_idx) + " " edouard@2641: + param[addr] + " " edouard@2641: + param[size]) edouard@2641: output.append(str(slave_idx) + "," + param[addr] + "," + result) edouard@2641: returnVal = output edouard@2641: """ edouard@2641: Edouard@2152: # ethercat sii_write -p (slave position) - (contents) Edouard@2152: SII_WRITE = """ Edouard@2152: import subprocess Edouard@2152: process = subprocess.Popen( Edouard@2152: ["ethercat", "-f", "sii_write", "-p", "%d", "-"], Edouard@2152: stdin=subprocess.PIPE) Edouard@2152: process.communicate(sii_data) Edouard@2152: returnVal = process.returncode Edouard@2152: """ Edouard@2152: Edouard@2152: # ethercat reg_write -p (slave position) -t (uinit16) (address) (data) Edouard@2152: REG_WRITE = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat reg_write -p %d -t uint16 %s %s") Edouard@2152: returnVal =result Edouard@2152: """ Edouard@2152: Edouard@2152: # ethercat rescan -p (slave position) Edouard@2152: RESCAN = """ Edouard@2152: import commands Edouard@2152: result = commands.getoutput("ethercat rescan -p %d") Edouard@2152: returnVal =result Edouard@2152: """ Edouard@2152: edouard@2641: # ethercat pdos edouard@2641: PDOS = """ edouard@2641: import commands edouard@2641: result = commands.getoutput("ethercat pdos -p 0") edouard@2641: returnVal =result edouard@2641: """ edouard@2641: Edouard@2152: #-------------------------------------------------- Edouard@2152: # Common Method For EtherCAT Management Edouard@2152: #-------------------------------------------------- Edouard@2152: class _CommonSlave: Edouard@2152: Edouard@2152: # ----- Data Structure for ethercat management ---- Edouard@2152: SlaveState = "" Edouard@2152: edouard@2641: # SDO base data type for Ethercatmaster edouard@2641: BaseDataTypes = { edouard@2641: "bool": ["BOOLEAN", "BOOL", "BIT"], edouard@2641: "uint8": ["BYTE", "USINT", "BIT1", "BIT2", "BIT3", "BIT4", "BIT5", "BIT6", edouard@2641: "BIT7", "BIT8", "BITARR8", "UNSIGNED8"], edouard@2641: "uint16": ["BITARR16", "UNSIGNED16", "UINT"], edouard@2641: "uint32": ["BITARR32", "UNSIGNED24", "UINT24", "UNSIGNED32", "UDINT"], edouard@2641: "uint64": ["UNSINED40", "UINT40", "UNSIGNED48", "UINT48", "UNSIGNED56", edouard@2641: "UINT56", "UNSIGNED64", "ULINT"], edouard@2641: "int8": ["INTEGER8", "SINT"], edouard@2641: "int16": ["INTEGER16", "INT"], edouard@2641: "int32": ["INTEGER24", "INT24", "INTEGER32", "DINT"], edouard@2641: "int64": ["INTEGER40", "INT40", "INTEGER48", "INT48", "INTEGER56", "INT56", edouard@2641: "INTEGER64", "LINT"], edouard@2641: "float": ["REAL", "REAL32"], edouard@2641: "double": ["LREAL", "REAL64"], edouard@2641: "string": ["VISUBLE_STRING", "STRING(n)"], edouard@2641: "octet_string": ["OCTET_STRING"], edouard@2641: "unicode_string": ["UNICODE_STRING"] edouard@2641: } edouard@2641: Edouard@2152: # category of SDO data Edouard@2152: DatatypeDescription, CommunicationObject, ManufacturerSpecific, \ Edouard@2152: ProfileSpecific, Reserved, AllSDOData = range(6) Edouard@2152: edouard@2641: # SDO data informations: index, sub-index, type, bit size, category-name edouard@2641: SDOVariables = [] edouard@2641: SDOSubEntryData = [] edouard@2641: edouard@2641: # defalut value of SDO data in XML edouard@2641: # Not Used edouard@2641: DefaultValueDic = {} Edouard@2152: Edouard@2152: # Flags for checking "write" permission of OD entries Edouard@2152: CheckPREOP = False Edouard@2152: CheckSAFEOP = False Edouard@2152: CheckOP = False Edouard@2152: Edouard@2152: # Save PDO Data Edouard@2152: TxPDOInfo = [] Edouard@2152: TxPDOCategory = [] Edouard@2152: RxPDOInfo = [] Edouard@2152: RxPDOCategory = [] Edouard@2152: Edouard@2152: # Save EEPROM Data Edouard@2152: SiiData = "" Edouard@2152: Edouard@2152: # Save Register Data Edouard@2152: RegData = "" Edouard@2152: CrtRegSpec = {"ESCType": "", Edouard@2152: "FMMUNumber": "", Edouard@2152: "SMNumber": "", Edouard@2152: "PDIType": ""} Edouard@2152: Edouard@2152: def __init__(self, controler): Edouard@2152: """ Edouard@2152: Constructor Edouard@2152: @param controler: _EthercatSlaveCTN class in EthercatSlave.py Edouard@2152: """ Edouard@2152: self.Controler = controler Edouard@2152: Edouard@2152: self.ClearSDODataSet() edouard@2641: Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: # Used Master State Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: def GetMasterState(self): Edouard@2152: """ Edouard@2152: Execute "ethercat master" command and parse the execution result Edouard@2152: @return MasterState Edouard@2152: """ Edouard@2152: # exectute "ethercat master" command Edouard@2152: error, return_val = self.Controler.RemoteExec(MASTER_STATE, return_val = None) Edouard@2152: master_state = {} Edouard@2152: # parse the reslut Edouard@2152: for each_line in return_val.splitlines(): Edouard@2152: if len(each_line) > 0 : Edouard@2152: chunks = each_line.strip().split(':', 1) Edouard@2152: key = chunks[0] Edouard@2152: value = [] Edouard@2152: if len(chunks) > 1 : Edouard@2152: value = chunks[1].split() Edouard@2152: if '(attached)' in value: Edouard@2152: value.remove('(attached)') Edouard@2152: master_state[key] = value Edouard@2152: Edouard@2152: return master_state Edouard@2152: Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: # Used Slave State Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: def RequestSlaveState(self, command): Edouard@2152: """ Edouard@2152: Set slave state to the specified one using "ethercat states -p %d %s" command. Edouard@2152: Command example : "ethercat states -p 0 PREOP" (target slave position and target state are given.) Edouard@2152: @param command : target slave state Edouard@2152: """ Edouard@2152: error, return_val = self.Controler.RemoteExec(SLAVE_STATE%(self.Controler.GetSlavePos(), command), return_val = None) Edouard@2152: Edouard@2152: def GetSlaveStateFromSlave(self): Edouard@2152: """ Edouard@2152: Get slave information using "ethercat slaves" command and store the information into internal data structure Edouard@2152: (self.SlaveState) for "Slave State" Edouard@2152: return_val example : 0 0:0 PREOP + EL9800 (V4.30) (PIC24, SPI, ET1100) Edouard@2152: """ Edouard@2152: error, return_val = self.Controler.RemoteExec(GET_SLAVE, return_val = None) Edouard@2152: self.SlaveState = return_val edouard@2641: return return_val Edouard@2152: Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: # Used SDO Management Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: def SDODownload(self, data_type, idx, sub_idx, value): Edouard@2152: """ Edouard@2152: Set an SDO object value to user-specified value using "ethercat download" command. Edouard@2152: Command example : "ethercat download --type int32 -p 0 0x8020 0x12 0x00000000" Edouard@2152: @param data_type : data type of SDO entry Edouard@2152: @param idx : index of the SDO entry Edouard@2152: @param sub_idx : subindex of the SDO entry Edouard@2152: @param value : value of SDO entry edouard@2641: """ edouard@2641: valid_type = self.GetValidDataType(data_type) edouard@2641: error, return_val = self.Controler.RemoteExec(SDO_DOWNLOAD%(valid_type, self.Controler.GetSlavePos(), idx, sub_idx, value), return_val = None) edouard@2641: edouard@2641: return return_val Edouard@2152: Edouard@2152: def BackupSDODataSet(self): Edouard@2152: """ Edouard@2152: Back-up current SDO entry information to restore the SDO data Edouard@2152: in case that the user cancels SDO update operation. Edouard@2152: """ Edouard@2152: self.BackupDatatypeDescription = self.SaveDatatypeDescription Edouard@2152: self.BackupCommunicationObject = self.SaveCommunicationObject Edouard@2152: self.BackupManufacturerSpecific = self.SaveManufacturerSpecific Edouard@2152: self.BackupProfileSpecific = self.SaveProfileSpecific Edouard@2152: self.BackupReserved = self.SaveReserved Edouard@2152: self.BackupAllSDOData = self.SaveAllSDOData Edouard@2152: Edouard@2152: def ClearSDODataSet(self): Edouard@2152: """ Edouard@2152: Clear the specified SDO entry information. Edouard@2152: """ Edouard@2152: for count in range(6): edouard@2641: self.SDOVariables.append([]) edouard@2641: edouard@2641: def GetAllSDOValuesFromSlave(self): edouard@2641: """ edouard@2641: Get SDO values of All SDO entries. edouard@2641: @return return_val: list of result of "SDO_UPLOAD" edouard@2641: """ edouard@2641: entry_infos = "" edouard@2641: alldata_idx = len(self.SDOVariables) edouard@2641: counter = 0 edouard@2641: for category in self.SDOVariables: edouard@2641: counter +=1 edouard@2641: # for avoid redundant repetition edouard@2641: if counter == alldata_idx: edouard@2641: continue edouard@2641: edouard@2641: for entry in category: edouard@2641: valid_type = self.GetValidDataType(entry["type"]) edouard@2641: for_command_string = "%s %s %s ," % \ edouard@2641: (valid_type, entry["idx"], entry["subIdx"]) edouard@2641: entry_infos += for_command_string edouard@2641: edouard@2641: error, return_val = self.Controler.RemoteExec(SDO_UPLOAD%(entry_infos, self.Controler.GetSlavePos()), return_val = None) edouard@2641: edouard@2641: return return_val edouard@2641: edouard@2641: def GetSDOValuesFromSlave(self, entries_info): edouard@2641: """ edouard@2641: Get SDO values of some SDO entries. edouard@2641: @param entries_info: dictionary of SDO entries that is wanted to know the value. edouard@2641: @return return_val: list of result of "SDO_UPLOAD" edouard@2641: """ edouard@2641: entry_infos = "" edouard@2641: edouard@2641: entries_info_list = entries_info.items() edouard@2641: entries_info_list.sort() edouard@2641: edouard@2641: for (idx, subIdx), entry in entries_info_list: edouard@2641: valid_type = self.GetValidDataType(entry["type"]) edouard@2641: for_command_string = "%s %s %s ," % \ edouard@2641: (valid_type, str(idx), str(subIdx)) edouard@2641: entry_infos += for_command_string edouard@2641: edouard@2641: error, return_val = self.Controler.RemoteExec(SDO_UPLOAD%(entry_infos, self.Controler.GetSlavePos()), return_val = None) edouard@2641: edouard@2641: return return_val edouard@2641: edouard@2641: def ExtractObjects(self): edouard@2641: """ edouard@2641: Extract object type items from imported ESI xml. edouard@2641: And they are stuctured as dictionary. edouard@2641: @return objects: dictionary of objects edouard@2641: """ edouard@2641: objects = {} edouard@2641: edouard@2641: slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) edouard@2641: type_infos = slave.getType() edouard@2641: device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) edouard@2641: edouard@2641: if device is not None : edouard@2641: for dictionary in device.GetProfileDictionaries(): edouard@2641: dictionary.load() edouard@2641: for object in dictionary.getObjects().getObject(): edouard@2641: object_index = ExtractHexDecValue(object.getIndex().getcontent()) edouard@2641: objects[(object_index)] = object edouard@2641: edouard@2641: return objects edouard@2641: edouard@2641: def ExtractAllDataTypes(self): edouard@2641: """ edouard@2641: Extract all data types from imported ESI xml. edouard@2641: @return dataTypes: dictionary of datatypes edouard@2641: """ edouard@2641: dataTypes = {} edouard@2641: edouard@2641: slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) edouard@2641: type_infos = slave.getType() edouard@2641: device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) edouard@2641: edouard@2641: for dictionary in device.GetProfileDictionaries(): edouard@2641: dictionary.load() edouard@2641: edouard@2641: datatypes = dictionary.getDataTypes() edouard@2641: if datatypes is not None: edouard@2641: edouard@2641: for datatype in datatypes.getDataType(): edouard@2641: dataTypes[datatype.getName()] = datatype edouard@2641: return dataTypes edouard@2641: edouard@2641: def IsBaseDataType(self, datatype): edouard@2641: """ edouard@2641: Check if the datatype is a base data type. edouard@2641: @return baseTypeFlag: true if datatype is a base data type, unless false edouard@2641: """ edouard@2641: baseTypeFlag = False edouard@2641: for baseDataTypeList in self.BaseDataTypes.values(): edouard@2641: if datatype in baseDataTypeList: edouard@2641: baseTypeFlag = True edouard@2641: break edouard@2641: return baseTypeFlag edouard@2641: edouard@2641: def GetBaseDataType(self, datatype): edouard@2641: """ edouard@2641: Get a base data type corresponding the datatype. edouard@2641: @param datatype: Some data type (string format) edouard@2641: @return base data type edouard@2641: """ edouard@2641: if self.IsBaseDataType(datatype): edouard@2641: return datatype edouard@2641: elif not datatype.find("STRING") == -1: edouard@2641: return datatype edouard@2641: else: edouard@2641: datatypes = self.ExtractAllDataTypes() edouard@2641: base_datatype = datatypes[datatype].getBaseType() edouard@2641: return self.GetBaseDataType(base_datatype) edouard@2641: edouard@2641: def GetValidDataType(self, datatype): edouard@2641: """ edouard@2641: Convert the datatype into a data type that is possible to download/upload edouard@2641: in etherlab master stack. edouard@2641: @param datatype: Some data type (string format) edouard@2641: @return base_type: vaild data type edouard@2641: """ edouard@2641: base_type = self.GetBaseDataType(datatype) edouard@2641: edouard@2641: if re.match("STRING\([0-9]*\)", datatype) is not None: edouard@2641: return "string" edouard@2641: else: edouard@2641: for key, value in self.BaseDataTypes.items(): edouard@2641: if base_type in value: edouard@2641: return key edouard@2641: return base_type edouard@2641: edouard@2641: # Not Used edouard@2641: def GetAllEntriesList(self): edouard@2641: """ edouard@2641: Get All entries information that includes index, sub-index, name, edouard@2641: type, bit size, PDO mapping, and default value. edouard@2641: @return self.entries: dictionary of entry edouard@2641: """ edouard@2641: slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) edouard@2641: type_infos = slave.getType() edouard@2641: device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) edouard@2641: self.entries = device.GetEntriesList() edouard@2641: datatypes = self.ExtractAllDataTypes() edouard@2641: objects = self.ExtractObjects() edouard@2641: entries_list = self.entries.items() edouard@2641: entries_list.sort() edouard@2641: edouard@2641: # append sub entries edouard@2641: for (index, subidx), entry in entries_list: edouard@2641: # entry_* is string type edouard@2641: entry_type = entry["Type"] edouard@2641: entry_index = entry["Index"] edouard@2641: edouard@2641: try: edouard@2641: object_info = objects[index].getInfo() edouard@2641: except: edouard@2641: continue edouard@2641: edouard@2641: if object_info is not None: edouard@2641: obj_content = object_info.getcontent() edouard@2641: edouard@2641: typeinfo = datatypes.get(entry_type, None) edouard@2641: bitsize = typeinfo.getBitSize() edouard@2641: type_content = typeinfo.getcontent() edouard@2641: edouard@2641: # ArrayInfo type edouard@2641: if type_content is not None and type_content["name"] == "ArrayInfo": edouard@2641: for arrayinfo in type_content["value"]: edouard@2641: element_num = arrayinfo.getElements() edouard@2641: first_subidx = arrayinfo.getLBound() edouard@2641: for offset in range(element_num): edouard@2641: new_subidx = int(first_subidx) + offset edouard@2641: entry_subidx = hex(new_subidx) edouard@2641: if obj_content["value"][new_subidx]["name"] == "SubItem": edouard@2641: subitem = obj_content["value"][new_subidx]["value"] edouard@2641: subname = subitem[new_subidx].getName() edouard@2641: if subname is not None: edouard@2641: entry_name = "%s - %s" % \ edouard@2641: (ExtractName(objects[index].getName()), subname) edouard@2641: else: edouard@2641: entry_name = ExtractName(objects[index].getName()) edouard@2641: self.entries[(index, new_subidx)] = { edouard@2641: "Index": entry_index, edouard@2641: "SubIndex": entry_subidx, edouard@2641: "Name": entry_name, edouard@2641: "Type": typeinfo.getBaseType(), edouard@2641: "BitSize": str(bitsize/element_num), edouard@2641: "Access": entry["Access"], edouard@2641: "PDOMapping": entry["PDOMapping"]} edouard@2641: try: edouard@2641: value_info = subitem[new_subidx].getInfo().getcontent()\ edouard@2641: ["value"][0]["value"][0] edouard@2641: self.AppendDefaultValue(index, new_subidx, value_info) edouard@2641: except: edouard@2641: pass edouard@2641: edouard@2641: try: edouard@2641: value_info = subitem[subidx].getInfo().getcontent()\ edouard@2641: ["value"][0]["value"][0] edouard@2641: self.AppendDefaultValue(index, subidx, value_info) edouard@2641: except: edouard@2641: pass edouard@2641: edouard@2641: # EnumInfo type edouard@2641: elif type_content is not None and type_content["name"] == "EnumInfo": edouard@2641: self.entries[(index, subidx)]["EnumInfo"] = {} edouard@2641: edouard@2641: for enuminfo in type_content["value"]: edouard@2641: text = enuminfo.getText() edouard@2641: enum = enuminfo.getEnum() edouard@2641: self.entries[(index, subidx)]["EnumInfo"][str(enum)] = text edouard@2641: edouard@2641: self.entries[(index, subidx)]["DefaultValue"] = "0x00" edouard@2641: edouard@2641: # another types edouard@2641: else: edouard@2641: if subidx == 0x00: edouard@2641: tmp_subidx = 0x00 edouard@2641: edouard@2641: try: edouard@2641: if obj_content["value"][tmp_subidx]["name"] == "SubItem": edouard@2641: sub_name = entry["Name"].split(" - ")[1] edouard@2641: for num in range(len(obj_content["value"])): edouard@2641: if sub_name == \ edouard@2641: obj_content["value"][num]["value"][num].getName(): edouard@2641: subitem_content = obj_content["value"][tmp_subidx]\ edouard@2641: ["value"][tmp_subidx] edouard@2641: value_info = subitem_content.getInfo().getcontent()\ edouard@2641: ["value"][0]["value"][0] edouard@2641: tmp_subidx += 1 edouard@2641: break edouard@2641: else: edouard@2641: value_info = None edouard@2641: edouard@2641: else: edouard@2641: value_info = \ edouard@2641: obj_content["value"][tmp_subidx]["value"][tmp_subidx] edouard@2641: edouard@2641: self.AppendDefaultValue(index, subidx, value_info) edouard@2641: edouard@2641: except: edouard@2641: pass edouard@2641: edouard@2641: return self.entries edouard@2641: edouard@2641: # Not Used edouard@2641: def AppendDefaultValue(self, index, subidx, value_info=None): edouard@2641: """ edouard@2641: Get the default value from the ESI xml edouard@2641: @param index: entry index edouard@2641: @param subidx: entry sub index edouard@2641: @param value_info: dictionary of infomation about default value edouard@2641: edouard@2641: """ edouard@2641: # there is not default value. edouard@2641: if value_info == None: edouard@2641: return edouard@2641: edouard@2641: raw_value = value_info["value"] edouard@2641: edouard@2641: # default value is hex binary type. edouard@2641: if value_info["name"] == "DefaultData": edouard@2641: raw_value_bit = list(hex(raw_value).split("0x")[1]) edouard@2641: edouard@2641: datatype = self.GetValidDataType(self.entries[(index, subidx)]["Type"]) edouard@2641: if datatype is "string" or datatype is "octet_string": edouard@2641: edouard@2641: if "L" in raw_value_bit: edouard@2641: raw_value_bit.remove("L") edouard@2641: edouard@2641: default_value = "".join(raw_value_bit).decode("hex") edouard@2641: edouard@2641: elif datatype is "unicode_string": edouard@2641: default_value = "".join(raw_value_bit).decode("hex").\ edouard@2641: decode("utf-8") edouard@2641: edouard@2641: else: edouard@2641: bit_num = len(raw_value_bit) edouard@2641: # padding edouard@2641: if not bit_num%2 == 0: edouard@2641: raw_value_bit.insert(0, "0") edouard@2641: edouard@2641: default_value_bit = [] edouard@2641: edouard@2641: # little endian -> big endian edouard@2641: for num in range(bit_num): edouard@2641: if num%2 == 0: edouard@2641: default_value_bit.insert(0, raw_value_bit[num]) edouard@2641: default_value_bit.insert(1, raw_value_bit[num+1]) edouard@2641: edouard@2641: default_value = "0x%s" % "".join(default_value_bit) edouard@2641: edouard@2641: # default value is string type. edouard@2641: # this case is not tested yet. edouard@2641: elif value_info["name"] == "DefaultString": edouard@2641: default_value = raw_value edouard@2641: edouard@2641: # default value is Hex or Dec type. edouard@2641: elif value_info["name"] == "DefaultValue": edouard@2641: default_value = "0x" + hex(ExtractHexDecValue(raw_value)) edouard@2641: edouard@2641: self.entries[(index, subidx)]["DefaultValue"] = default_value edouard@2641: Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: # Used PDO Monitoring Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: def RequestPDOInfo(self): Edouard@2152: """ edouard@2641: Load slave information from RootClass (XML data) and parse the information edouard@2641: (calling SlavePDOData() method). Edouard@2152: """ Edouard@2152: # Load slave information from ESI XML file (def EthercatMaster.py) Edouard@2152: slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) Edouard@2152: Edouard@2152: type_infos = slave.getType() Edouard@2152: device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) Edouard@2152: # Initialize PDO data set Edouard@2152: self.ClearDataSet() Edouard@2152: Edouard@2152: # if 'device' object is valid, call SavePDOData() to parse PDO data Edouard@2152: if device is not None : Edouard@2152: self.SavePDOData(device) Edouard@2152: Edouard@2152: def SavePDOData(self, device): Edouard@2152: """ Edouard@2152: Parse PDO data and store the results in TXPDOCategory and RXPDOCategory edouard@2641: Tx(Rx)PDOCategory : index, name, entry number, exclude list, Sm Edouard@2152: Tx(Rx)Info : entry index, sub index, name, length, type Edouard@2152: @param device : Slave information extracted from ESI XML file Edouard@2152: """ Edouard@2152: # Parsing TXPDO entries Edouard@2152: for pdo, pdo_info in ([(pdo, "Inputs") for pdo in device.getTxPdo()]): Edouard@2152: # Save pdo_index, entry, and name of each entry Edouard@2152: pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) Edouard@2152: entries = pdo.getEntry() Edouard@2152: pdo_name = ExtractName(pdo.getName()) edouard@2641: excludes = pdo.getExclude() edouard@2641: exclude_list = [] edouard@2641: Sm = pdo.getSm() edouard@2641: edouard@2641: if excludes : edouard@2641: for exclude in excludes: edouard@2641: exclude_list.append(ExtractHexDecValue(exclude.getcontent())) edouard@2641: Edouard@2152: # Initialize entry number count Edouard@2152: count = 0 edouard@2641: Edouard@2152: # Parse entries Edouard@2152: for entry in entries: Edouard@2152: # Save index and subindex Edouard@2152: index = ExtractHexDecValue(entry.getIndex().getcontent()) Edouard@2152: subindex = ExtractHexDecValue(entry.getSubIndex()) Edouard@2152: # if entry name exists, save entry data Edouard@2152: if ExtractName(entry.getName()) is not None : Edouard@2152: entry_infos = { Edouard@2152: "entry_index" : index, Edouard@2152: "subindex" : subindex, Edouard@2152: "name" : ExtractName(entry.getName()), edouard@2641: "bitlen" : entry.getBitLen()} edouard@2641: if entry.getDataType() is not None: edouard@2641: entry_infos["type"] = entry.getDataType().getcontent() Edouard@2152: self.TxPDOInfo.append(entry_infos) Edouard@2152: count += 1 edouard@2641: edouard@2641: categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "sm" : Sm, edouard@2641: "number_of_entry" : count, "exclude_list" : exclude_list} Edouard@2152: self.TxPDOCategory.append(categorys) Edouard@2152: Edouard@2152: # Parsing RxPDO entries Edouard@2152: for pdo, pdo_info in ([(pdo, "Outputs") for pdo in device.getRxPdo()]): Edouard@2152: # Save pdo_index, entry, and name of each entry Edouard@2152: pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent()) Edouard@2152: entries = pdo.getEntry() Edouard@2152: pdo_name = ExtractName(pdo.getName()) edouard@2641: excludes = pdo.getExclude() edouard@2641: exclude_list = [] edouard@2641: Sm = pdo.getSm() edouard@2641: edouard@2641: if excludes : edouard@2641: for exclude in excludes: edouard@2641: exclude_list.append(ExtractHexDecValue(exclude.getcontent())) edouard@2641: Edouard@2152: # Initialize entry number count Edouard@2152: count = 0 Edouard@2152: Edouard@2152: # Parse entries Edouard@2152: for entry in entries: Edouard@2152: # Save index and subindex Edouard@2152: index = ExtractHexDecValue(entry.getIndex().getcontent()) Edouard@2152: subindex = ExtractHexDecValue(entry.getSubIndex()) Edouard@2152: # if entry name exists, save entry data Edouard@2152: if ExtractName(entry.getName()) is not None : Edouard@2152: entry_infos = { Edouard@2152: "entry_index" : index, Edouard@2152: "subindex" : subindex, Edouard@2152: "name" : ExtractName(entry.getName()), edouard@2641: "bitlen" : entry.getBitLen()} edouard@2641: if entry.getDataType() is not None: edouard@2641: entry_infos["type"] = entry.getDataType().getcontent() Edouard@2152: self.RxPDOInfo.append(entry_infos) Edouard@2152: count += 1 Edouard@2152: edouard@2641: categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "sm" : Sm, edouard@2641: "number_of_entry" : count, "exclude_list" : exclude_list} Edouard@2152: self.RxPDOCategory.append(categorys) Edouard@2152: Edouard@2152: def GetTxPDOCategory(self): Edouard@2152: """ Edouard@2152: Get TxPDOCategory data structure (Meta informaton of TxPDO). Edouard@2152: TxPDOCategorys : index, name, number of entries Edouard@2152: @return TxPDOCategorys Edouard@2152: """ Edouard@2152: return self.TxPDOCategory Edouard@2152: Edouard@2152: def GetRxPDOCategory(self): Edouard@2152: """ Edouard@2152: Get RxPDOCategory data structure (Meta information of RxPDO). Edouard@2152: RxPDOCategorys : index, name, number of entries Edouard@2152: @return RxPDOCategorys Edouard@2152: """ Edouard@2152: return self.RxPDOCategory Edouard@2152: Edouard@2152: def GetTxPDOInfo(self): Edouard@2152: """ Edouard@2152: Get TxPDOInfo data structure (Detailed information on TxPDO entries). Edouard@2152: TxPDOInfos : entry index, sub index, name, length, type Edouard@2152: @return TxPDOInfos Edouard@2152: """ Edouard@2152: return self.TxPDOInfo Edouard@2152: Edouard@2152: def GetRxPDOInfo(self): Edouard@2152: """ Edouard@2152: Get RxPDOInfo data structure (Detailed information on RxPDO entries). Edouard@2152: RxPDOInfos : entry index, sub index, name, length, type Edouard@2152: @return RxPDOInfos Edouard@2152: """ Edouard@2152: return self.RxPDOInfo Edouard@2152: Edouard@2152: def ClearDataSet(self): Edouard@2152: """ Edouard@2152: Initialize PDO management data structure. Edouard@2152: """ edouard@2641: self.TxPDOInfo = [] edouard@2641: self.TxPDOCategory = [] edouard@2641: self.RxPDOInfo = [] edouard@2641: self.RxPDOCategory = [] Edouard@2152: Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: # Used EEPROM Management Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: # Base data types in ETG2000; format = {"Name": "BitSize"} Edouard@2152: BaseDataTypeDict = {"BOOL": "01", Edouard@2152: "SINT": "02", Edouard@2152: "INT": "03", Edouard@2152: "DINT": "04", Edouard@2152: "USINT": "05", Edouard@2152: "UINT": "06", Edouard@2152: "UDINT": "07", Edouard@2152: "REAL": "08", Edouard@2152: "INT24": "10", Edouard@2152: "LREAL": "11", Edouard@2152: "INT40": "12", Edouard@2152: "INT48": "13", Edouard@2152: "INT56": "14", Edouard@2152: "LINT": "15", Edouard@2152: "UINT24": "16", Edouard@2152: "UINT40": "18", Edouard@2152: "UINT48": "19", Edouard@2152: "UINT56": "1a", Edouard@2152: "ULINT": "1b", Edouard@2152: "USINT": "1e", Edouard@2152: "BITARR8": "2d", Edouard@2152: "BITARR16": "2e", Edouard@2152: "BITARR32": "2f", Edouard@2152: "BIT1": "30", Edouard@2152: "BIT2": "31", Edouard@2152: "BIT3": "32", Edouard@2152: "BIT4": "33", Edouard@2152: "BIT5": "34", Edouard@2152: "BIT6": "35", Edouard@2152: "BIT7": "36", Edouard@2152: "BIT8": "37"} Edouard@2152: Edouard@2152: def GetSmartViewInfos(self): Edouard@2152: """ Edouard@2152: Parse XML data for "Smart View" of EEPROM contents. Edouard@2152: @return smartview_infos : EEPROM contents dictionary Edouard@2152: """ Edouard@2152: Edouard@2152: smartview_infos = {"eeprom_size": 128, Edouard@2152: "pdi_type": 0, Edouard@2152: "device_emulation": "False", Edouard@2152: "vendor_id": '0x00000000', Edouard@2152: "product_code": '0x00000000', Edouard@2152: "revision_no": '0x00000000', Edouard@2152: "serial_no": '0x00000000', Edouard@2152: "supported_mailbox": "", Edouard@2152: "mailbox_bootstrapconf_outstart": '0', Edouard@2152: "mailbox_bootstrapconf_outlength": '0', Edouard@2152: "mailbox_bootstrapconf_instart": '0', Edouard@2152: "mailbox_bootstrapconf_inlength": '0', Edouard@2152: "mailbox_standardconf_outstart": '0', Edouard@2152: "mailbox_standardconf_outlength": '0', Edouard@2152: "mailbox_standardconf_instart": '0', Edouard@2152: "mailbox_standardconf_inlength": '0'} Edouard@2152: Edouard@2152: slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) Edouard@2152: type_infos = slave.getType() Edouard@2152: device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) Edouard@2152: edouard@2641: #from decimal import Decimal edouard@2641: Edouard@2152: # 'device' represents current slave device selected by user Edouard@2152: if device is not None: edouard@2641: # dir() method print available method list edouard@2641: #print dir(device.getEeprom().getchildren()[1]) edouard@2641: edouard@2641: # success get subitem second object edouard@2641: #print objectify.fromstring(device.getEeprom().getchildren()[1].tostring()).text edouard@2641: edouard@2641: for eeprom_element in device.getEeprom().getchildren(): Edouard@2152: # get EEPROM size; -- edouard@2641: if eeprom_element.tag == "ByteSize": edouard@2641: smartview_infos["eeprom_size"] = objectify.fromstring(eeprom_element.tostring()).text Edouard@2152: edouard@2641: elif eeprom_element.tag == "ConfigData": edouard@2641: # ConfigData Field Datatype??? edouard@2641: #print type(objectify.fromstring(eeprom_element.tostring()).text) edouard@2641: configData_data = self.DecimalToHex(objectify.fromstring(eeprom_element.tostring()).text) Edouard@2152: # get PDI type; -- address 0x00 Edouard@2152: smartview_infos["pdi_type"] = int(configData_data[0:2], 16) Edouard@2152: # get state of device emulation; -- address 0x01 edouard@2641: if len(configData_data) > 3 and "{:0>8b}".format(int(configData_data[2:4], 16))[7] == '1': Edouard@2152: smartview_infos["device_emulation"] = "True" Edouard@2152: edouard@2641: elif eeprom_element.tag == "BootStrap": edouard@2641: bootstrap_data = "{:0>16x}".format(int(objectify.fromstring(eeprom_element.tostring()).text, 16)) Edouard@2152: # get bootstrap configuration; -- Edouard@2152: for cfg, iter in [("mailbox_bootstrapconf_outstart", 0), Edouard@2152: ("mailbox_bootstrapconf_outlength", 1), Edouard@2152: ("mailbox_bootstrapconf_instart", 2), Edouard@2152: ("mailbox_bootstrapconf_inlength", 3)]: Edouard@2152: smartview_infos[cfg] = str(int(bootstrap_data[4*iter+2:4*(iter+1)]+bootstrap_data[4*iter:4*iter+2], 16)) Edouard@2152: edouard@2641: """ edouard@2641: for eeprom_element in device.getEeprom().getcontent()["value"]: edouard@2641: # get EEPROM size; -- edouard@2641: if eeprom_element["name"] == "ByteSize": edouard@2641: smartview_infos["eeprom_size"] = eeprom_element["value"] edouard@2641: edouard@2641: elif eeprom_element["name"] == "ConfigData": edouard@2641: configData_data = self.DecimalToHex(eeprom_element["value"]) edouard@2641: # get PDI type; -- address 0x00 edouard@2641: smartview_infos["pdi_type"] = int(configData_data[0:2], 16) edouard@2641: # get state of device emulation; -- address 0x01 edouard@2641: if "{:0>8b}".format(int(configData_data[2:4], 16))[7] == '1': edouard@2641: smartview_infos["device_emulation"] = "True" edouard@2641: edouard@2641: elif eeprom_element["name"] == "BootStrap": edouard@2641: bootstrap_data = "{:0>16x}".format(eeprom_element["value"]) edouard@2641: # get bootstrap configuration; -- edouard@2641: for cfg, iter in [("mailbox_bootstrapconf_outstart", 0), edouard@2641: ("mailbox_bootstrapconf_outlength", 1), edouard@2641: ("mailbox_bootstrapconf_instart", 2), edouard@2641: ("mailbox_bootstrapconf_inlength", 3)]: edouard@2641: smartview_infos[cfg] = str(int(bootstrap_data[4*iter+2:4*(iter+1)]+bootstrap_data[4*iter:4*iter+2], 16)) edouard@2641: """ edouard@2641: Edouard@2152: # get protocol (profile) types supported by mailbox; - edouard@2641: for mailbox_protocol in ["VoE", "SoE", "FoE", "CoE", "EoE", "AoE"]: edouard@2641: if device.getMailbox() is not None and eval("device.getMailbox().get%s()"%mailbox_protocol) is not None: edouard@2641: smartview_infos["supported_mailbox"] += "%s, "%mailbox_protocol Edouard@2152: smartview_infos["supported_mailbox"] = smartview_infos["supported_mailbox"].strip(", ") Edouard@2152: Edouard@2152: # get standard configuration of mailbox; - Edouard@2152: for sm_element in device.getSm(): Edouard@2152: if sm_element.getcontent() == "MBoxOut": Edouard@2152: smartview_infos["mailbox_standardconf_outstart"] = str(ExtractHexDecValue(sm_element.getStartAddress())) Edouard@2152: smartview_infos["mailbox_standardconf_outlength"] = str(ExtractHexDecValue(sm_element.getDefaultSize())) Edouard@2152: elif sm_element.getcontent() == "MBoxIn": Edouard@2152: smartview_infos["mailbox_standardconf_instart"] = str(ExtractHexDecValue(sm_element.getStartAddress())) Edouard@2152: smartview_infos["mailbox_standardconf_inlength"] = str(ExtractHexDecValue(sm_element.getDefaultSize())) Edouard@2152: else: Edouard@2152: pass Edouard@2152: Edouard@2152: # get device identity from - edouard@2641: # vendor ID; by default, pre-defined value in self.ModulesLibrary edouard@2641: # if device type in 'vendor' item equals to actual slave device type, set 'vendor_id' to vendor ID. Edouard@2152: for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): Edouard@2152: for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]: Edouard@2152: if available_device[0] == type_infos["device_type"]: Edouard@2152: smartview_infos["vendor_id"] = "0x" + "{:0>8x}".format(vendor_id) Edouard@2152: edouard@2641: # product code; Edouard@2152: if device.getType().getProductCode() is not None: Edouard@2152: product_code = device.getType().getProductCode() Edouard@2152: smartview_infos["product_code"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(product_code)) Edouard@2152: edouard@2641: # revision number; Edouard@2152: if device.getType().getRevisionNo() is not None: Edouard@2152: revision_no = device.getType().getRevisionNo() Edouard@2152: smartview_infos["revision_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(revision_no)) Edouard@2152: edouard@2641: # serial number; Edouard@2152: if device.getType().getSerialNo() is not None: Edouard@2152: serial_no = device.getType().getSerialNo() Edouard@2152: smartview_infos["serial_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(serial_no)) Edouard@2152: Edouard@2152: return smartview_infos Edouard@2152: Edouard@2152: else: Edouard@2152: return None Edouard@2152: Edouard@2152: def DecimalToHex(self, decnum): Edouard@2152: """ Edouard@2152: Convert decimal value into hexadecimal representation. Edouard@2152: @param decnum : decimal value Edouard@2152: @return hex_data : hexadecimal representation of input value in decimal Edouard@2152: """ edouard@2641: value = "%x" % int(decnum, 16) Edouard@2152: value_len = len(value) Edouard@2152: if (value_len % 2) == 0: Edouard@2152: hex_len = value_len Edouard@2152: else: Edouard@2152: hex_len = (value_len / 2) * 2 + 2 edouard@2641: edouard@2641: hex_data = ("{:0>"+str(hex_len)+"x}").format(int(decnum, 16)) Edouard@2152: Edouard@2152: return hex_data Edouard@2152: Edouard@2152: def SiiRead(self): Edouard@2152: """ Edouard@2152: Get slave EEPROM contents maintained by master device using "ethercat sii_read -p %d" command. Edouard@2152: Command example : "ethercat sii_read -p 0" Edouard@2152: @return return_val : result of "ethercat sii_read" (binary data) Edouard@2152: """ Edouard@2152: error, return_val = self.Controler.RemoteExec(SII_READ%(self.Controler.GetSlavePos()), return_val = None) Edouard@2152: self.SiiData = return_val Edouard@2152: return return_val Edouard@2152: Edouard@2152: def SiiWrite(self, binary): Edouard@2152: """ Edouard@2152: Overwrite slave EEPROM contents using "ethercat sii_write -p %d" command. Edouard@2152: Command example : "ethercat sii_write -p 0 - (binary contents)" Edouard@2152: @param binary : EEPROM contents in binary data format Edouard@2152: @return return_val : result of "ethercat sii_write" (If it succeeds, the return value is NULL.) Edouard@2152: """ Edouard@2152: error, return_val = self.Controler.RemoteExec(SII_WRITE%(self.Controler.GetSlavePos()), return_val = None, sii_data = binary) Edouard@2152: return return_val Edouard@2152: Edouard@2152: def LoadData(self): Edouard@2152: """ Edouard@2152: Loading data from EEPROM use Sii_Read Method Edouard@2152: @return self.BinaryCode : slave EEPROM data in binary format (zero-padded) Edouard@2152: """ Edouard@2152: return_val = self.Controler.CommonMethod.SiiRead() Edouard@2152: self.BinaryCode = return_val Edouard@2152: self.Controler.SiiData = self.BinaryCode Edouard@2152: Edouard@2152: # append zero-filled padding data up to EEPROM size Edouard@2152: for index in range(self.SmartViewInfosFromXML["eeprom_size"] - len(self.BinaryCode)): Edouard@2152: self.BinaryCode = self.BinaryCode +'ff'.decode('hex') Edouard@2152: Edouard@2152: return self.BinaryCode Edouard@2152: Edouard@2152: def HexRead(self, binary): Edouard@2152: """ Edouard@2152: Convert binary digit representation into hexadecimal representation for "Hex View" menu. Edouard@2152: @param binary : binary digits Edouard@2152: @return hexCode : hexadecimal digits Edouard@2152: @return hexview_table_row, hexview_table_col : Grid size for "Hex View" UI Edouard@2152: """ Edouard@2152: row_code = [] Edouard@2152: row_text = "" Edouard@2152: row = 0 Edouard@2152: hex_code = [] Edouard@2152: Edouard@2152: hexview_table_col = 17 Edouard@2152: Edouard@2152: for index in range(0, len(binary)) : Edouard@2152: if len(binary[index]) != 1: Edouard@2152: break Edouard@2152: else: Edouard@2152: digithexstr = hex(ord(binary[index])) Edouard@2152: Edouard@2152: tempvar2 = digithexstr[2:4] Edouard@2152: if len(tempvar2) == 1: Edouard@2152: tempvar2 = "0" + tempvar2 Edouard@2152: row_code.append(tempvar2) Edouard@2152: Edouard@2152: if int(digithexstr, 16)>=32 and int(digithexstr, 16)<=126: Edouard@2152: row_text = row_text + chr(int(digithexstr, 16)) Edouard@2152: else: Edouard@2152: row_text = row_text + "." Edouard@2152: Edouard@2152: if index != 0 : Edouard@2152: if len(row_code) == (hexview_table_col - 1): Edouard@2152: row_code.append(row_text) Edouard@2152: hex_code.append(row_code) Edouard@2152: row_text = "" Edouard@2152: row_code = [] Edouard@2152: row = row + 1 Edouard@2152: Edouard@2152: hexview_table_row = row Edouard@2152: Edouard@2152: return hex_code, hexview_table_row, hexview_table_col Edouard@2152: Edouard@2152: def GenerateEEPROMList(self, data, direction, length): Edouard@2152: """ Edouard@2152: Generate EEPROM data list by reconstructing 'data' string. Edouard@2152: example : data="12345678", direction=0, length=8 -> eeprom_list=['12', '34', '56', '78'] Edouard@2152: data="12345678", direction=1, length=8 -> eeprom_list=['78', '56', '34', '12'] Edouard@2152: @param data : string to be reconstructed Edouard@2152: @param direction : endianness Edouard@2152: @param length : data length Edouard@2152: @return eeprom_list : reconstructed list data structure Edouard@2152: """ Edouard@2152: eeprom_list = [] Edouard@2152: Edouard@2152: if direction is 0 or 1: Edouard@2152: for i in range(length/2): Edouard@2152: if data == "": Edouard@2152: eeprom_list.append("00") Edouard@2152: else: Edouard@2152: eeprom_list.append(data[direction*(length-2):direction*(length-2)+2]) Edouard@2152: data = data[(1-direction)*2:length-direction*2] Edouard@2152: length -= 2 Edouard@2152: return eeprom_list Edouard@2152: Edouard@2152: def XmlToEeprom(self): Edouard@2152: """ Edouard@2152: Extract slave EEPROM contents using slave ESI XML file. Edouard@2152: - Mandatory parts Edouard@2152: - String category : ExtractEEPROMStringCategory() Edouard@2152: - General category : ExtractEEPROMGeneralCategory() Edouard@2152: - FMMU category : ExtractEEPROMFMMUCategory Edouard@2152: - SyncM category : ExtractEEPROMSyncMCategory() Edouard@2152: - Tx/RxPDO category : ExtractEEPROMPDOCategory() Edouard@2152: - DC category : ExtractEEPROMDCCategory() Edouard@2152: @return eeprom_binary Edouard@2152: """ Edouard@2152: eeprom = [] Edouard@2152: data = "" Edouard@2152: eeprom_size = 0 Edouard@2152: eeprom_binary = "" Edouard@2152: Edouard@2152: # 'device' is the slave device of the current EtherCAT slave plugin Edouard@2152: slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) Edouard@2152: type_infos = slave.getType() Edouard@2152: device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) edouard@2641: Edouard@2152: if device is not None: Edouard@2152: # get ConfigData for EEPROM offset 0x0000-0x000d; -- edouard@2641: # Modify by jblee because of update IDE module (minidom -> lxml) edouard@2641: for eeprom_element in device.getEeprom().getchildren(): edouard@2641: if eeprom_element.tag == "ConfigData": edouard@2641: data = self.DecimalToHex(objectify.fromstring(eeprom_element.tostring()).text) Edouard@2152: eeprom += self.GenerateEEPROMList(data, 0, 28) Edouard@2152: Edouard@2152: # calculate CRC for EEPROM offset 0x000e-0x000f Edouard@2152: crc = 0x48 Edouard@2152: for segment in eeprom: Edouard@2152: for i in range(8): Edouard@2152: bit = crc & 0x80 Edouard@2152: crc = (crc << 1) | ((int(segment, 16) >> (7 - i)) & 0x01) Edouard@2152: if bit: Edouard@2152: crc ^= 0x07 Edouard@2152: for k in range(8): Edouard@2152: bit = crc & 0x80 Edouard@2152: crc <<= 1 Edouard@2152: if bit: Edouard@2152: crc ^= 0x07 Edouard@2152: eeprom.append(hex(crc)[len(hex(crc))-3:len(hex(crc))-1]) Edouard@2152: eeprom.append("00") Edouard@2152: Edouard@2152: # get VendorID for EEPROM offset 0x0010-0x0013; Edouard@2152: data = "" Edouard@2152: for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): Edouard@2152: for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]: Edouard@2152: if available_device[0] == type_infos["device_type"]: Edouard@2152: data = "{:0>8x}".format(vendor_id) Edouard@2152: eeprom += self.GenerateEEPROMList(data, 1, 8) Edouard@2152: Edouard@2152: # get Product Code for EEPROM offset 0x0014-0x0017; Edouard@2152: data = "" Edouard@2152: if device.getType().getProductCode() is not None: Edouard@2152: data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getProductCode())) Edouard@2152: eeprom += self.GenerateEEPROMList(data, 1, 8) Edouard@2152: Edouard@2152: # get Revision Number for EEPROM offset 0x0018-0x001b; Edouard@2152: data = "" Edouard@2152: if device.getType().getRevisionNo() is not None: Edouard@2152: data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getRevisionNo())) Edouard@2152: eeprom += self.GenerateEEPROMList(data, 1, 8) Edouard@2152: Edouard@2152: # get Serial Number for EEPROM 0x001c-0x001f; Edouard@2152: data = "" Edouard@2152: if device.getType().getSerialNo() is not None: Edouard@2152: data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getSerialNo())) Edouard@2152: eeprom += self.GenerateEEPROMList(data, 1, 8) Edouard@2152: Edouard@2152: # get Execution Delay for EEPROM 0x0020-0x0021; not analyzed yet Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: Edouard@2152: # get Port0/1 Delay for EEPROM offset 0x0022-0x0025; not analyzed yet Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: Edouard@2152: # reserved for EEPROM offset 0x0026-0x0027; Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: edouard@2641: data = "" Edouard@2152: # get BootStrap for EEPROM offset 0x0028-0x002e; -- edouard@2641: # Modify by jblee because of update IDE module (minidom -> lxml) edouard@2641: for eeprom_element in device.getEeprom().getchildren(): edouard@2641: if eeprom_element.tag == "BootStrap": edouard@2641: data = "{:0>16x}".format(int(objectify.fromstring(eeprom_element.tostring()).text, 16)) Edouard@2152: eeprom += self.GenerateEEPROMList(data, 0, 16) Edouard@2152: Edouard@2152: # get Standard Mailbox for EEPROM offset 0x0030-0x0037; - Edouard@2152: data = "" edouard@2641: standard_receive_mailbox_offset = None edouard@2641: standard_receive_mailbox_size = None Edouard@2163: standard_send_mailbox_offset = None Edouard@2163: standard_send_mailbox_size = None Edouard@2152: for sm_element in device.getSm(): Edouard@2152: if sm_element.getcontent() == "MBoxOut": Edouard@2152: standard_receive_mailbox_offset = "{:0>4x}".format(ExtractHexDecValue(sm_element.getStartAddress())) Edouard@2152: standard_receive_mailbox_size = "{:0>4x}".format(ExtractHexDecValue(sm_element.getDefaultSize())) Edouard@2152: elif sm_element.getcontent() == "MBoxIn": Edouard@2152: standard_send_mailbox_offset = "{:0>4x}".format(ExtractHexDecValue(sm_element.getStartAddress())) Edouard@2152: standard_send_mailbox_size = "{:0>4x}".format(ExtractHexDecValue(sm_element.getDefaultSize())) Edouard@2152: Edouard@2152: if standard_receive_mailbox_offset is None: Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(standard_receive_mailbox_offset[2:4]) Edouard@2152: eeprom.append(standard_receive_mailbox_offset[0:2]) Edouard@2152: if standard_receive_mailbox_size is None: Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(standard_receive_mailbox_size[2:4]) Edouard@2152: eeprom.append(standard_receive_mailbox_size[0:2]) Edouard@2152: if standard_send_mailbox_offset is None: Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(standard_send_mailbox_offset[2:4]) Edouard@2152: eeprom.append(standard_send_mailbox_offset[0:2]) Edouard@2152: if standard_send_mailbox_size is None: Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(standard_send_mailbox_size[2:4]) Edouard@2152: eeprom.append(standard_send_mailbox_size[0:2]) Edouard@2152: Edouard@2152: # get supported mailbox protocols for EEPROM offset 0x0038-0x0039; Edouard@2152: data = 0 edouard@2641: if device.getMailbox() is not None: edouard@2641: for mbox, bit in [(device.getMailbox().getAoE(), 0), edouard@2641: (device.getMailbox().getEoE(), 1), edouard@2641: (device.getMailbox().getCoE(), 2), edouard@2641: (device.getMailbox().getFoE(), 3), edouard@2641: (device.getMailbox().getSoE(), 4), edouard@2641: (device.getMailbox().getVoE(), 5)]: edouard@2641: if mbox is not None: Edouard@2163: data += 1< lxml) Edouard@2152: data = "" edouard@2641: for eeprom_element in device.getEeprom().getchildren(): edouard@2641: if eeprom_element.tag == "ByteSize": edouard@2641: eeprom_size = int(objectify.fromstring(eeprom_element.tostring()).text) edouard@2641: data = "{:0>4x}".format(eeprom_size/1024*8-1) edouard@2641: Edouard@2152: if data == "": Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(data[2:4]) Edouard@2152: eeprom.append(data[0:2]) Edouard@2152: Edouard@2152: # Version for EEPROM 0x007e-0x007f; edouard@2641: # According to "EtherCAT Slave Device Description(V0.3.0)" Edouard@2152: eeprom.append("01") Edouard@2152: eeprom.append("00") Edouard@2152: Edouard@2152: # append String Category data Edouard@2152: for data in self.ExtractEEPROMStringCategory(device): Edouard@2152: eeprom.append(data) Edouard@2152: Edouard@2152: # append General Category data Edouard@2152: for data in self.ExtractEEPROMGeneralCategory(device): Edouard@2152: eeprom.append(data) Edouard@2152: Edouard@2152: # append FMMU Category data Edouard@2152: for data in self.ExtractEEPROMFMMUCategory(device): Edouard@2152: eeprom.append(data) Edouard@2152: Edouard@2152: # append SyncM Category data Edouard@2152: for data in self.ExtractEEPROMSyncMCategory(device): Edouard@2152: eeprom.append(data) Edouard@2152: Edouard@2152: # append TxPDO Category data Edouard@2152: for data in self.ExtractEEPROMPDOCategory(device, "TxPdo"): Edouard@2152: eeprom.append(data) Edouard@2152: Edouard@2152: # append RxPDO Category data Edouard@2152: for data in self.ExtractEEPROMPDOCategory(device, "RxPdo"): Edouard@2152: eeprom.append(data) Edouard@2152: Edouard@2152: # append DC Category data Edouard@2152: for data in self.ExtractEEPROMDCCategory(device): Edouard@2152: eeprom.append(data) Edouard@2152: Edouard@2152: # append padding Edouard@2152: padding = eeprom_size-len(eeprom) Edouard@2152: for i in range(padding): Edouard@2152: eeprom.append("ff") Edouard@2152: Edouard@2152: # convert binary code Edouard@2152: for index in range(eeprom_size): Edouard@2152: eeprom_binary = eeprom_binary + eeprom[index].decode('hex') Edouard@2152: Edouard@2152: return eeprom_binary Edouard@2152: Edouard@2152: def ExtractEEPROMStringCategory(self, device): Edouard@2152: """ Edouard@2152: Extract "Strings" category data from slave ESI XML and generate EEPROM image data. Edouard@2152: @param device : 'device' object in the slave ESI XML Edouard@2152: @return eeprom : "Strings" category EEPROM image data Edouard@2152: """ Edouard@2152: eeprom = [] Edouard@2152: self.Strings = [] Edouard@2152: data = "" Edouard@2152: count = 0 # string counter Edouard@2152: padflag = False # padding flag if category length is odd Edouard@2152: Edouard@2152: # index information for General Category in EEPROM Edouard@2152: self.GroupIdx = 0 Edouard@2152: self.ImgIdx = 0 Edouard@2152: self.OrderIdx = 0 Edouard@2152: self.NameIdx = 0 Edouard@2152: Edouard@2152: # flag for preventing duplicated vendor specific data Edouard@2152: typeflag = False Edouard@2152: grouptypeflag = False Edouard@2152: groupnameflag = False Edouard@2152: devnameflag = False Edouard@2152: imageflag = False Edouard@2152: Edouard@2152: # vendor specific data edouard@2641: # element1; ---- edouard@2641: # vendor_specific_data : vendor specific data (binary type) edouard@2641: # Modify by jblee because of update IDE module (minidom -> lxml) Edouard@2152: vendor_specific_data = "" edouard@2641: # vendor_spec_strings : list of vendor specific "strings" for preventing duplicated strings Edouard@2152: vendor_spec_strings = [] Edouard@2152: for element in device.getType().getcontent(): Edouard@2152: data += element edouard@2641: # retrun type change unicode -> str edouard@2641: if data is not "" and type(data) == str: Edouard@2152: for vendor_spec_string in vendor_spec_strings: Edouard@2152: if data == vendor_spec_string: Edouard@2152: self.OrderIdx = vendor_spec_strings.index(data)+1 Edouard@2152: typeflag = True Edouard@2152: break Edouard@2152: if typeflag is False: Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: vendor_spec_strings.append(data) Edouard@2152: typeflag = True Edouard@2152: self.OrderIdx = count Edouard@2152: vendor_specific_data += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: vendor_specific_data += "{:0>2x}".format(ord(data[character])) Edouard@2152: data = "" Edouard@2152: edouard@2641: # element2-1; ---- edouard@2641: # Modify by jblee because of update IDE module (minidom -> lxml) Edouard@2152: data = device.getGroupType() edouard@2641: # retrun type change unicode -> str edouard@2641: if data is not None and type(data) == str: Edouard@2152: for vendor_spec_string in vendor_spec_strings: Edouard@2152: if data == vendor_spec_string: Edouard@2152: self.GroupIdx = vendor_spec_strings.index(data)+1 Edouard@2152: grouptypeflag = True Edouard@2152: break Edouard@2152: if grouptypeflag is False: Edouard@2152: grouptype = data Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: vendor_spec_strings.append(data) Edouard@2152: grouptypeflag = True Edouard@2152: self.GroupIdx = count Edouard@2152: vendor_specific_data += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: vendor_specific_data += "{:0>2x}".format(ord(data[character])) Edouard@2152: edouard@2641: # element2-2; --- Edouard@2152: if grouptypeflag is False: Edouard@2152: if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None: Edouard@2152: for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): Edouard@2152: for group_type, group_etc in vendor["groups"].iteritems(): Edouard@2152: for device_item in group_etc["devices"]: Edouard@2152: if device == device_item[1]: Edouard@2152: data = group_type Edouard@2152: if data is not None and type(data) == unicode: Edouard@2152: for vendor_spec_string in vendor_spec_strings: Edouard@2152: if data == vendor_spec_string: Edouard@2152: self.GroupIdx = vendor_spec_strings.index(data)+1 Edouard@2152: grouptypeflag = True Edouard@2152: break Edouard@2152: if grouptypeflag is False: Edouard@2152: grouptype = data Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: vendor_spec_strings.append(data) Edouard@2152: grouptypeflag = True Edouard@2152: self.GroupIdx = count Edouard@2152: vendor_specific_data += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: vendor_specific_data += "{:0>2x}".format(ord(data[character])) Edouard@2152: data = "" edouard@2641: edouard@2641: # element3; ---- edouard@2641: # Modify by jblee because of update IDE module (minidom -> lxml) edouard@2641: if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None: edouard@2641: LcId_obj = self.Controler.CTNParent.CTNParent.ModulesLibrary.LcId_data edouard@2641: data = LcId_obj.getcontent() edouard@2641: edouard@2641: # retrun type change unicode -> str edouard@2641: if data is not "" and type(data) == str: edouard@2641: for vendor_spec_string in vendor_spec_strings: edouard@2641: if data == vendor_spec_string: edouard@2641: groupnameflag = True edouard@2641: break edouard@2641: if groupnameflag is False: edouard@2641: count += 1 edouard@2641: self.Strings.append(data) edouard@2641: vendor_spec_strings.append(data) edouard@2641: groupnameflag = True edouard@2641: vendor_specific_data += "{:0>2x}".format(len(data)) edouard@2641: for character in range(len(data)): edouard@2641: vendor_specific_data += "{:0>2x}".format(ord(data[character])) edouard@2641: edouard@2641: """ edouard@2641: # element3; ---- Edouard@2152: if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None: Edouard@2152: for vendorId, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): Edouard@2152: for group_type, group_etc in vendor["groups"].iteritems(): Edouard@2152: for device_item in group_etc["devices"]: Edouard@2152: if device == device_item[1]: Edouard@2152: data = group_etc["name"] Edouard@2152: if data is not "" and type(data) == unicode: Edouard@2152: for vendor_spec_string in vendor_spec_strings: Edouard@2152: if data == vendor_spec_string: Edouard@2152: groupnameflag = True Edouard@2152: break Edouard@2152: if groupnameflag is False: Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: vendor_spec_strings.append(data) Edouard@2152: groupnameflag = True Edouard@2152: vendor_specific_data += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: vendor_specific_data += "{:0>2x}".format(ord(data[character])) edouard@2641: """ edouard@2641: Edouard@2152: data = "" Edouard@2152: edouard@2641: # element4; ---- edouard@2641: # Modify by jblee because of update IDE module (minidom -> lxml) Edouard@2152: for element in device.getName(): Edouard@2152: if element.getLcId() == 1 or element.getLcId()==1033: Edouard@2152: data = element.getcontent() edouard@2641: # retrun type change unicode -> str edouard@2641: if data is not "" and type(data) == str: Edouard@2152: for vendor_spec_string in vendor_spec_strings: Edouard@2152: if data == vendor_spec_string: Edouard@2152: self.NameIdx = vendor_spec_strings.index(data)+1 Edouard@2152: devnameflag = True Edouard@2152: break Edouard@2152: if devnameflag is False: Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: vendor_spec_strings.append(data) Edouard@2152: devnameflag = True Edouard@2152: self.NameIdx = count Edouard@2152: vendor_specific_data += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: vendor_specific_data += "{:0>2x}".format(ord(data[character])) edouard@2641: Edouard@2152: data = "" Edouard@2152: edouard@2641: # element5-1; ---- Edouard@2152: if device.getcontent() is not None: edouard@2641: #data = device.getcontent()["value"] edouard@2641: # mod by jblee 151224 edouard@2641: # xml module change minidom -> lxml edouard@2641: # use lxml objectify module edouard@2641: data = objectify.fromstring(device.getcontent().tostring()).text edouard@2641: # retrun type change unicode -> str edouard@2641: if data is not None and type(data) == str: Edouard@2152: for vendor_spec_string in vendor_spec_strings: Edouard@2152: if data == vendor_spec_string: Edouard@2152: self.ImgIdx = vendor_spec_strings.index(data)+1 Edouard@2152: imageflag = True Edouard@2152: break Edouard@2152: if imageflag is False: Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: vendor_spec_strings.append(data) Edouard@2152: imageflag = True Edouard@2152: self.ImgIdx = count Edouard@2152: vendor_specific_data += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: vendor_specific_data += "{:0>2x}".format(ord(data[character])) edouard@2641: edouard@2641: # element5-2; ---- edouard@2641: # Modify by jblee because of update IDE module (minidom -> lxml) edouard@2641: if imageflag is False: edouard@2641: if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None: edouard@2641: data_obj = self.Controler.CTNParent.CTNParent.ModulesLibrary.Image16x14_data edouard@2641: data = data_obj.text edouard@2641: edouard@2641: # retrun type change unicode -> str edouard@2641: if data is not None and type(data) == str: edouard@2641: for vendor_spec_string in vendor_spec_strings: edouard@2641: if data == vendor_spec_string: edouard@2641: self.ImgIdx = vendor_spec_strings.index(data)+1 edouard@2641: imageflag = True edouard@2641: break edouard@2641: if imageflag is False: edouard@2641: count += 1 edouard@2641: self.Strings.append(data) edouard@2641: vendor_spec_strings.append(data) edouard@2641: imageflag = True edouard@2641: self.ImgIdx = count edouard@2641: vendor_specific_data += "{:0>2x}".format(len(data)) edouard@2641: for character in range(len(data)): edouard@2641: vendor_specific_data += "{:0>2x}".format(ord(data[character])) edouard@2641: edouard@2641: """ edouard@2641: # element5-2; ---- Edouard@2152: if imageflag is False: Edouard@2152: if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None: Edouard@2152: for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems(): Edouard@2152: for group_type, group_etc in vendor["groups"].iteritems(): Edouard@2152: for device_item in group_etc["devices"]: Edouard@2152: if device == device_item[1]: edouard@2641: print group_etc edouard@2641: data = group_etc["value"] edouard@2641: # retrun type change unicode -> str edouard@2641: if data is not None and type(data) == str: Edouard@2152: for vendor_spec_string in vendor_spec_strings: Edouard@2152: if data == vendor_spec_string: Edouard@2152: self.ImgIdx = vendor_spec_strings.index(data)+1 Edouard@2152: imageflag = True Edouard@2152: break Edouard@2152: if imageflag is False: Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: vendor_spec_strings.append(data) Edouard@2152: imageflag = True Edouard@2152: self.ImgIdx = count Edouard@2152: vendor_specific_data += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: vendor_specific_data += "{:0>2x}".format(ord(data[character])) edouard@2641: """ edouard@2641: Edouard@2152: data = "" Edouard@2152: # DC related elements edouard@2641: # ------ Edouard@2152: dc_related_elements = "" Edouard@2152: if device.getDc() is not None: Edouard@2152: for element in device.getDc().getOpMode(): Edouard@2152: data = element.getName() Edouard@2152: if data is not "": Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: dc_related_elements += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: dc_related_elements += "{:0>2x}".format(ord(data[character])) Edouard@2152: data = "" Edouard@2152: Edouard@2152: # Input elements(TxPDO) edouard@2641: # ----; Name Edouard@2152: input_elements = "" Edouard@2152: inputs = [] Edouard@2152: for element in device.getTxPdo(): Edouard@2152: for name in element.getName(): Edouard@2152: data = name.getcontent() Edouard@2152: for input in inputs: Edouard@2152: if data == input: Edouard@2152: data = "" Edouard@2152: if data is not "": Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: inputs.append(data) Edouard@2152: input_elements += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: input_elements += "{:0>2x}".format(ord(data[character])) Edouard@2152: data = "" Edouard@2152: for entry in element.getEntry(): Edouard@2152: for name in entry.getName(): Edouard@2152: data = name.getcontent() Edouard@2152: for input in inputs: Edouard@2152: if data == input: Edouard@2152: data = "" Edouard@2152: if data is not "": Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: inputs.append(data) Edouard@2152: input_elements += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: input_elements += "{:0>2x}".format(ord(data[character])) Edouard@2152: data = "" Edouard@2152: Edouard@2152: # Output elements(RxPDO) edouard@2641: # ----; Name Edouard@2152: output_elements = "" Edouard@2152: outputs = [] Edouard@2152: for element in device.getRxPdo(): Edouard@2152: for name in element.getName(): Edouard@2152: data = name.getcontent() Edouard@2152: for output in outputs: Edouard@2152: if data == output: Edouard@2152: data = "" Edouard@2152: if data is not "": Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: outputs.append(data) Edouard@2152: output_elements += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: output_elements += "{:0>2x}".format(ord(data[character])) Edouard@2152: data = "" Edouard@2152: for entry in element.getEntry(): Edouard@2152: for name in entry.getName(): Edouard@2152: data = name.getcontent() Edouard@2152: for output in outputs: Edouard@2152: if data == output: Edouard@2152: data = "" Edouard@2152: if data is not "": Edouard@2152: count += 1 Edouard@2152: self.Strings.append(data) Edouard@2152: outputs.append(data) Edouard@2152: output_elements += "{:0>2x}".format(len(data)) Edouard@2152: for character in range(len(data)): Edouard@2152: output_elements += "{:0>2x}".format(ord(data[character])) Edouard@2152: data = "" Edouard@2152: Edouard@2152: # form eeprom data edouard@2641: # category header Edouard@2152: eeprom.append("0a") Edouard@2152: eeprom.append("00") edouard@2641: # category length (word); 1 word is 4 bytes. "+2" is the length of string's total number Edouard@2152: length = len(vendor_specific_data + dc_related_elements + input_elements + output_elements) + 2 Edouard@2152: if length%4 == 0: Edouard@2152: pass Edouard@2152: else: Edouard@2152: length +=length%4 Edouard@2152: padflag = True Edouard@2152: eeprom.append("{:0>4x}".format(length/4)[2:4]) Edouard@2152: eeprom.append("{:0>4x}".format(length/4)[0:2]) edouard@2641: # total numbers of strings Edouard@2152: eeprom.append("{:0>2x}".format(count)) Edouard@2152: for element in [vendor_specific_data, Edouard@2152: dc_related_elements, Edouard@2152: input_elements, Edouard@2152: output_elements]: Edouard@2152: for iter in range(len(element)/2): Edouard@2152: if element == "": Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(element[0:2]) Edouard@2152: element = element[2:len(element)] Edouard@2152: # padding if length is odd bytes Edouard@2152: if padflag is True: Edouard@2152: eeprom.append("ff") Edouard@2152: Edouard@2152: return eeprom Edouard@2152: Edouard@2152: def ExtractEEPROMGeneralCategory(self, device): Edouard@2152: """ Edouard@2152: Extract "General" category data from slave ESI XML and generate EEPROM image data. Edouard@2152: @param device : 'device' object in the slave ESI XML Edouard@2152: @return eeprom : "Strings" category EEPROM image data Edouard@2152: """ Edouard@2152: eeprom = [] Edouard@2152: data = "" Edouard@2152: Edouard@2152: # category header Edouard@2152: eeprom.append("1e") Edouard@2152: eeprom.append("00") Edouard@2152: Edouard@2152: # category length Edouard@2152: eeprom.append("10") Edouard@2152: eeprom.append("00") Edouard@2152: Edouard@2152: # word 1 : Group Type index and Image index in STRINGS Category Edouard@2152: eeprom.append("{:0>2x}".format(self.GroupIdx)) Edouard@2152: eeprom.append("{:0>2x}".format(self.ImgIdx)) Edouard@2152: Edouard@2152: # word 2 : Device Type index and Device Name index in STRINGS Category Edouard@2152: eeprom.append("{:0>2x}".format(self.OrderIdx)) Edouard@2152: eeprom.append("{:0>2x}".format(self.NameIdx)) Edouard@2152: Edouard@2152: # word 3 : Physical Layer Port info. and CoE Details Edouard@2152: eeprom.append("01") # Physical Layer Port info - assume 01 edouard@2641: # CoE Details; ----- Edouard@2152: coe_details = 0 edouard@2641: if device.getMailbox() is not None and device.getMailbox().getCoE() is not None: edouard@2641: coe_details = 1 # sdo enabled edouard@2641: for attr, bit in [(device.getMailbox().getCoE().getSdoInfo(), 1), edouard@2641: (device.getMailbox().getCoE().getPdoAssign(), 2), edouard@2641: (device.getMailbox().getCoE().getPdoConfig(), 3), edouard@2641: (device.getMailbox().getCoE().getPdoUpload(), 4), edouard@2641: (device.getMailbox().getCoE().getCompleteAccess(), 5)]: edouard@2641: if attr==1 or attr==True: edouard@2641: coe_details += 1<2x}".format(coe_details)) Edouard@2152: Edouard@2152: # word 4 : FoE Details and EoE Details edouard@2641: # FoE Details; ----- edouard@2641: if device.getMailbox() is not None and device.getMailbox().getFoE() is not None: Edouard@2152: eeprom.append("01") Edouard@2152: else: Edouard@2152: eeprom.append("00") edouard@2641: # EoE Details; ----- edouard@2641: if device.getMailbox() is not None and device.getMailbox().getEoE() is not None: Edouard@2152: eeprom.append("01") Edouard@2152: else: Edouard@2152: eeprom.append("00") Edouard@2152: Edouard@2152: # word 5 : SoE Channels(reserved) and DS402 Channels edouard@2641: # SoE Details; ----- edouard@2641: if device.getMailbox() is not None and device.getMailbox().getSoE() is not None: Edouard@2152: eeprom.append("01") Edouard@2152: else: Edouard@2152: eeprom.append("00") edouard@2641: # DS402Channels; -----: DS402Channels edouard@2641: if device.getMailbox() is not None and \ edouard@2641: (device.getMailbox().getCoE().getDS402Channels() == True \ edouard@2641: or device.getMailbox().getCoE().getDS402Channels() == 1): edouard@2641: eeprom.append("01") edouard@2641: else: edouard@2641: eeprom.append("00") Edouard@2152: Edouard@2152: # word 6 : SysmanClass(reserved) and Flags Edouard@2152: eeprom.append("00") # reserved edouard@2641: # Flags Edouard@2152: en_safeop = False Edouard@2152: en_lrw = False Edouard@2152: if device.getType().getTcCfgModeSafeOp() == True \ Edouard@2152: or device.getType().getTcCfgModeSafeOp() == 1: Edouard@2152: en_safeop = True Edouard@2152: if device.getType().getUseLrdLwr() == True \ Edouard@2152: or device.getType().getUseLrdLwr() == 1: Edouard@2152: en_lrw = True Edouard@2152: Edouard@2152: flags = "0b"+"000000"+str(int(en_lrw))+str(int(en_safeop)) Edouard@2152: eeprom.append("{:0>2x}".format(int(flags, 2))) Edouard@2152: Edouard@2152: # word 7 : Current On EBus (assume 0x0000) Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: # after word 7; couldn't analyze yet Edouard@2152: eeprom.append("03") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("11") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") Edouard@2152: Edouard@2152: return eeprom Edouard@2152: Edouard@2152: def ExtractEEPROMFMMUCategory(self, device): Edouard@2152: """ Edouard@2152: Extract "FMMU" category data from slave ESI XML and generate EEPROM image data. Edouard@2152: @param device : 'device' object in the slave ESI XML Edouard@2152: @return eeprom : "Strings" category EEPROM image data Edouard@2152: """ Edouard@2152: eeprom = [] Edouard@2152: data = "" Edouard@2152: count = 0 # number of FMMU Edouard@2152: padflag = False Edouard@2152: Edouard@2152: for fmmu in device.getFmmu(): Edouard@2152: count += 1 Edouard@2152: if fmmu.getcontent() == "Outputs": Edouard@2152: data += "01" Edouard@2152: if fmmu.getcontent() == "Inputs": Edouard@2152: data += "02" Edouard@2152: if fmmu.getcontent() == "MBoxState": Edouard@2152: data += "03" Edouard@2152: Edouard@2152: # construct of EEPROM data Edouard@2152: if data is not "": edouard@2641: # category header Edouard@2152: eeprom.append("28") Edouard@2152: eeprom.append("00") edouard@2641: # category length Edouard@2152: if count%2 == 1: Edouard@2152: padflag = True Edouard@2152: eeprom.append("{:0>4x}".format((count+1)/2)[2:4]) Edouard@2152: eeprom.append("{:0>4x}".format((count+1)/2)[0:2]) Edouard@2152: else: Edouard@2152: eeprom.append("{:0>4x}".format((count)/2)[2:4]) Edouard@2152: eeprom.append("{:0>4x}".format((count)/2)[0:2]) Edouard@2152: for i in range(count): Edouard@2152: if data == "": Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(data[0:2]) Edouard@2152: data = data[2:len(data)] edouard@2641: # padding if length is odd bytes Edouard@2152: if padflag is True: Edouard@2152: eeprom.append("ff") Edouard@2152: Edouard@2152: return eeprom Edouard@2152: Edouard@2152: def ExtractEEPROMSyncMCategory(self, device): Edouard@2152: """ Edouard@2152: Extract "SyncM" category data from slave ESI XML and generate EEPROM image data. Edouard@2152: @param device : 'device' object in the slave ESI XML Edouard@2152: @return eeprom : "Strings" category EEPROM image data Edouard@2152: """ Edouard@2152: eeprom = [] Edouard@2152: data = "" Edouard@2152: number = {"MBoxOut":"01", "MBoxIn":"02", "Outputs":"03", "Inputs":"04"} Edouard@2152: Edouard@2152: for sm in device.getSm(): Edouard@2152: for attr in [sm.getStartAddress(), Edouard@2152: sm.getDefaultSize(), Edouard@2152: sm.getControlByte()]: Edouard@2152: if attr is not None: Edouard@2152: data += "{:0>4x}".format(ExtractHexDecValue(attr))[2:4] Edouard@2152: data += "{:0>4x}".format(ExtractHexDecValue(attr))[0:2] Edouard@2152: else: Edouard@2152: data += "0000" Edouard@2152: if sm.getEnable() == "1" or sm.getEnable() == True: Edouard@2152: data += "01" Edouard@2152: else: Edouard@2152: data += "00" Edouard@2152: data += number[sm.getcontent()] Edouard@2152: Edouard@2152: if data is not "": edouard@2641: # category header Edouard@2152: eeprom.append("29") Edouard@2152: eeprom.append("00") edouard@2641: # category length Edouard@2152: eeprom.append("{:0>4x}".format(len(data)/4)[2:4]) Edouard@2152: eeprom.append("{:0>4x}".format(len(data)/4)[0:2]) Edouard@2152: for i in range(len(data)/2): Edouard@2152: if data == "": Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(data[0:2]) Edouard@2152: data = data[2:len(data)] Edouard@2152: Edouard@2152: return eeprom Edouard@2152: Edouard@2152: def ExtractEEPROMPDOCategory(self, device, pdotype): Edouard@2152: """ Edouard@2152: Extract ""PDO (Tx, Rx)"" category data from slave ESI XML and generate EEPROM image data. Edouard@2152: @param device : 'device' object in the slave ESI XML Edouard@2152: @param pdotype : identifier whether "TxPDO" or "RxPDO". Edouard@2152: @return eeprom : "Strings" category EEPROM image data Edouard@2152: """ Edouard@2152: eeprom = [] Edouard@2152: data = "" Edouard@2152: count = 0 Edouard@2152: en_fixed = False Edouard@2152: en_mandatory = False Edouard@2152: en_virtual = False Edouard@2152: Edouard@2152: for element in eval("device.get%s()"%pdotype): edouard@2641: # PDO Index Edouard@2152: data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[2:4] Edouard@2152: data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[0:2] edouard@2641: # Number of Entries Edouard@2152: data += "{:0>2x}".format(len(element.getEntry())) edouard@2641: # About Sync Manager Edouard@2152: if element.getSm() is not None: Edouard@2152: data += "{:0>2x}".format(element.getSm()) Edouard@2152: else: Edouard@2152: data += "ff" edouard@2641: # Reference to DC Synch (according to ET1100 documentation) - assume 0 Edouard@2152: data += "00" edouard@2641: # Name Index Edouard@2152: objname = "" Edouard@2152: for name in element.getName(): Edouard@2152: objname = name.getcontent() Edouard@2152: for name in self.Strings: Edouard@2152: count += 1 Edouard@2152: if objname == name: Edouard@2152: break Edouard@2152: if len(self.Strings)+1 == count: Edouard@2152: data += "00" Edouard@2152: else: Edouard@2152: data += "{:0>2x}".format(count) Edouard@2152: count = 0 edouard@2641: # Flags; by Fixed, Mandatory, Virtual attributes ? Edouard@2152: if element.getFixed() == True or 1: Edouard@2152: en_fixed = True Edouard@2152: if element.getMandatory() == True or 1: Edouard@2152: en_mandatory = True Edouard@2152: if element.getVirtual() == True or element.getVirtual(): Edouard@2152: en_virtual = True Edouard@2152: data += str(int(en_fixed)) + str(int(en_mandatory)) + str(int(en_virtual)) + "0" Edouard@2152: Edouard@2152: for entry in element.getEntry(): edouard@2641: # Entry Index Edouard@2152: data += "{:0>4x}".format(ExtractHexDecValue(entry.getIndex().getcontent()))[2:4] Edouard@2152: data += "{:0>4x}".format(ExtractHexDecValue(entry.getIndex().getcontent()))[0:2] edouard@2641: # Subindex Edouard@2152: data += "{:0>2x}".format(int(entry.getSubIndex())) edouard@2641: # Entry Name Index Edouard@2152: objname = "" Edouard@2152: for name in entry.getName(): Edouard@2152: objname = name.getcontent() Edouard@2152: for name in self.Strings: Edouard@2152: count += 1 Edouard@2152: if objname == name: Edouard@2152: break Edouard@2152: if len(self.Strings)+1 == count: Edouard@2152: data += "00" Edouard@2152: else: Edouard@2152: data += "{:0>2x}".format(count) Edouard@2152: count = 0 edouard@2641: # DataType Edouard@2152: if entry.getDataType() is not None: Edouard@2152: if entry.getDataType().getcontent() in self.BaseDataTypeDict: Edouard@2152: data += self.BaseDataTypeDict[entry.getDataType().getcontent()] Edouard@2152: else: Edouard@2152: data += "00" Edouard@2152: else: Edouard@2152: data += "00" edouard@2641: # BitLen Edouard@2152: if entry.getBitLen() is not None: Edouard@2152: data += "{:0>2x}".format(int(entry.getBitLen())) Edouard@2152: else: Edouard@2152: data += "00" edouard@2641: # Flags; by Fixed attributes ? Edouard@2152: en_fixed = False Edouard@2152: if entry.getFixed() == True or entry.getFixed() == 1: Edouard@2152: en_fixed = True Edouard@2152: data += str(int(en_fixed)) + "000" Edouard@2152: Edouard@2152: if data is not "": edouard@2641: # category header Edouard@2152: if pdotype == "TxPdo": Edouard@2152: eeprom.append("32") Edouard@2152: elif pdotype == "RxPdo": Edouard@2152: eeprom.append("33") Edouard@2152: else: Edouard@2152: eeprom.append("00") Edouard@2152: eeprom.append("00") edouard@2641: # category length Edouard@2152: eeprom.append("{:0>4x}".format(len(data)/4)[2:4]) Edouard@2152: eeprom.append("{:0>4x}".format(len(data)/4)[0:2]) Edouard@2152: data = str(data.lower()) Edouard@2152: for i in range(len(data)/2): Edouard@2152: if data == "": Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(data[0:2]) Edouard@2152: data = data[2:len(data)] Edouard@2152: Edouard@2152: return eeprom Edouard@2152: Edouard@2152: def ExtractEEPROMDCCategory(self, device): Edouard@2152: """ Edouard@2152: Extract "DC(Distributed Clock)" category data from slave ESI XML and generate EEPROM image data. Edouard@2152: @param device : 'device' object in the slave ESI XML Edouard@2152: @return eeprom : "Strings" category EEPROM image data Edouard@2152: """ Edouard@2152: eeprom = [] Edouard@2152: data = "" Edouard@2152: count = 0 Edouard@2152: namecount = 0 Edouard@2152: Edouard@2152: if device.getDc() is not None: Edouard@2152: for element in device.getDc().getOpMode(): Edouard@2152: count += 1 edouard@2641: # assume that word 1-7 are 0x0000 Edouard@2152: data += "0000" Edouard@2152: data += "0000" Edouard@2152: data += "0000" Edouard@2152: data += "0000" Edouard@2152: data += "0000" Edouard@2152: data += "0000" Edouard@2152: data += "0000" edouard@2641: # word 8-10 edouard@2641: # AssignActivate Edouard@2152: if element.getAssignActivate() is not None: Edouard@2152: data += "{:0>4x}".format(ExtractHexDecValue(element.getAssignActivate()))[2:4] Edouard@2152: data += "{:0>4x}".format(ExtractHexDecValue(element.getAssignActivate()))[0:2] Edouard@2152: else: Edouard@2152: data += "0000" edouard@2641: # Factor of CycleTimeSync0 ? and default is 1? Edouard@2152: if element.getCycleTimeSync0() is not None: Edouard@2152: if element.getCycleTimeSync0().getFactor() is not None: Edouard@2152: data += "{:0>2x}".format(int(element.getCycleTimeSync0().getFactor())) Edouard@2152: data += "00" Edouard@2152: else: Edouard@2152: data += "0100" Edouard@2152: else: Edouard@2152: data += "0100" edouard@2641: # Index of Name in STRINGS Category edouard@2641: # Name Index Edouard@2152: objname = "" Edouard@2152: for name in element.getName(): Edouard@2152: objname += name Edouard@2152: for name in self.Strings: Edouard@2152: namecount += 1 Edouard@2152: if objname == name: Edouard@2152: break Edouard@2152: if len(self.Strings)+1 == namecount: Edouard@2152: data += "00" Edouard@2152: else: Edouard@2152: data += "{:0>2x}".format(namecount) Edouard@2152: namecount = 0 Edouard@2152: data += "00" edouard@2641: # assume that word 11-12 are 0x0000 Edouard@2152: data += "0000" Edouard@2152: data += "0000" Edouard@2152: Edouard@2152: if data is not "": edouard@2641: # category header Edouard@2152: eeprom.append("3c") Edouard@2152: eeprom.append("00") edouard@2641: # category length Edouard@2152: eeprom.append("{:0>4x}".format(len(data)/4)[2:4]) Edouard@2152: eeprom.append("{:0>4x}".format(len(data)/4)[0:2]) Edouard@2152: data = str(data.lower()) Edouard@2152: for i in range(len(data)/2): Edouard@2152: if data == "": Edouard@2152: eeprom.append("00") Edouard@2152: else: Edouard@2152: eeprom.append(data[0:2]) Edouard@2152: data = data[2:len(data)] Edouard@2152: Edouard@2152: return eeprom Edouard@2152: Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: # Used Register Access Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: def RegRead(self, offset, length): Edouard@2152: """ Edouard@2152: Read slave ESC register content using "ethercat reg_read -p %d %s %s" command. Edouard@2152: Command example : "ethercat reg_read -p 0 0x0c00 0x0400" Edouard@2152: @param offset : register address Edouard@2152: @param length : register length Edouard@2152: @return return_val : register data Edouard@2152: """ Edouard@2152: error, return_val = self.Controler.RemoteExec(REG_READ%(self.Controler.GetSlavePos(), offset, length), return_val = None) Edouard@2152: return return_val Edouard@2152: edouard@2641: def MultiRegRead(self, slave_num, reg_infos): edouard@2641: """ edouard@2641: edouard@2641: @slave_num: edouard@2641: @param addr_info: edouard@2641: @return return_val: edouard@2641: """ edouard@2641: reg_info_str = "" edouard@2641: for reg_info in reg_infos: edouard@2641: reg_info_str = reg_info_str + "%s|" % reg_info edouard@2641: reg_info_str = reg_info_str.strip("|") edouard@2641: edouard@2641: error, return_val = self.Controler.RemoteExec(\ edouard@2641: MULTI_REG_READ%(slave_num, reg_info_str), edouard@2641: return_val = None) edouard@2641: edouard@2641: return return_val edouard@2641: Edouard@2152: def RegWrite(self, address, data): Edouard@2152: """ Edouard@2152: Write data to slave ESC register using "ethercat reg_write -p %d %s %s" command. Edouard@2152: Command example : "ethercat reg_write -p 0 0x0c04 0x0001" Edouard@2152: @param address : register address Edouard@2152: @param data : data to write Edouard@2152: @return return_val : the execution result of "ethercat reg_write" (for error check) Edouard@2152: """ Edouard@2152: error, return_val = self.Controler.RemoteExec(REG_WRITE%(self.Controler.GetSlavePos(), address, data), return_val = None) Edouard@2152: return return_val Edouard@2152: Edouard@2152: def Rescan(self): Edouard@2152: """ Edouard@2152: Synchronize EEPROM data in master controller with the data in slave device after EEPROM write. Edouard@2152: Command example : "ethercat rescan -p 0" Edouard@2152: """ Edouard@2152: error, return_val = self.Controler.RemoteExec(RESCAN%(self.Controler.GetSlavePos()), return_val = None) edouard@2641: edouard@2641: #------------------------------------------------------------------------------- edouard@2641: # Used DC Configuration edouard@2641: #------------------------------------------------------------------------------- edouard@2641: def LoadESIData(self): edouard@2641: return_data = [] edouard@2641: slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos()) edouard@2641: type_infos = slave.getType() edouard@2641: device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos) edouard@2641: if device.getDc() is not None: edouard@2641: for OpMode in device.getDc().getOpMode(): edouard@2641: temp_data = { edouard@2641: "desc" : OpMode.getDesc() if OpMode.getDesc() is not None else "Unused", edouard@2641: "assign_activate" : OpMode.getAssignActivate() \ edouard@2641: if OpMode.getAssignActivate() is not None else "#x0000", edouard@2641: "cycletime_sync0" : OpMode.getCycleTimeSync0().getcontent() \ edouard@2641: if OpMode.getCycleTimeSync0() is not None else None, edouard@2641: "shifttime_sync0" : OpMode.getShiftTimeSync0().getcontent() \ edouard@2641: if OpMode.getShiftTimeSync0() is not None else None, edouard@2641: "cycletime_sync1" : OpMode.getShiftTimeSync1().getcontent() \ edouard@2641: if OpMode.getShiftTimeSync1() is not None else None, edouard@2641: "shifttime_sync1" : OpMode.getShiftTimeSync1().getcontent() \ edouard@2641: if OpMode.getShiftTimeSync1() is not None else None edouard@2641: } edouard@2641: edouard@2641: if OpMode.getCycleTimeSync0() is not None: edouard@2641: temp_data["cycletime_sync0_factor"] = OpMode.getCycleTimeSync0().getFactor() edouard@2641: edouard@2641: if OpMode.getCycleTimeSync1() is not None: edouard@2641: temp_data["cycletime_sync1_factor"] = OpMode.getCycleTimeSync1().getFactor() edouard@2641: edouard@2641: return_data.append(temp_data) edouard@2641: edouard@2641: return return_data Edouard@2152: Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: # Common Use Methods Edouard@2152: #------------------------------------------------------------------------------- Edouard@2152: def CheckConnect(self, cyclic_flag): Edouard@2152: """ Edouard@2152: Check connection status (1) between Beremiz and the master (2) between the master and the slave. Edouard@2152: @param cyclic_flag: 0 - one shot, 1 - periodic Edouard@2152: @return True or False edouard@2641: """ Edouard@2152: if self.Controler.GetCTRoot()._connector is not None: Edouard@2152: # Check connection between the master and the slave. Edouard@2152: # Command example : "ethercat xml -p 0" Edouard@2152: error, return_val = self.Controler.RemoteExec(SLAVE_XML%(self.Controler.GetSlavePos()), return_val = None) Edouard@2152: number_of_lines = return_val.split("\n") Edouard@2152: if len(number_of_lines) <= 2 : # No slave connected to the master controller Edouard@2152: if not cyclic_flag : Edouard@2152: self.CreateErrorDialog('No connected slaves') Edouard@2152: return False Edouard@2152: Edouard@2152: elif len(number_of_lines) > 2 : Edouard@2152: return True Edouard@2152: else: Edouard@2152: # The master controller is not connected to Beremiz host Edouard@2152: if not cyclic_flag : Edouard@2152: self.CreateErrorDialog('PLC not connected!') Edouard@2152: return False Edouard@2152: Edouard@2152: def CreateErrorDialog(self, mention): Edouard@2152: """ Edouard@2152: Create a dialog to indicate error or warning. Edouard@2152: @param mention : Error String Edouard@2152: """ Edouard@2152: app_frame = self.Controler.GetCTRoot().AppFrame Edouard@2152: dlg = wx.MessageDialog (app_frame, mention, Edouard@2152: ' Warning...', Edouard@2152: wx.OK | wx.ICON_INFORMATION) Edouard@2152: dlg.ShowModal() Edouard@2152: dlg.Destroy()