etherlab/CommonEtherCATFunction.py
changeset 2152 e6946c298a42
child 2163 6ea6d83e7280
equal deleted inserted replaced
2151:015dab6a915f 2152:e6946c298a42
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of Beremiz, an Integrated Development Environment for
       
     5 #programming IEC 61131-3 automates supporting EtherCAT. 
       
     6 #
       
     7 #Copyright (C) 2013: Real-Time & Embedded Systems (RTES) Lab. University of Seoul, Korea
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
       
    19 #General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 
       
    26 import os
       
    27 import wx
       
    28 
       
    29 def ExtractHexDecValue(value):
       
    30     """
       
    31      convert numerical value in string format into decimal or hex format.
       
    32      @param value : hex or decimal data
       
    33      @return integer data
       
    34     """
       
    35     try:
       
    36         return int(value)
       
    37     except:
       
    38         pass
       
    39     try:
       
    40         return int(value.replace("#", "0"), 16)
       
    41         
       
    42     except:
       
    43         raise ValueError, "Invalid value for HexDecValue \"%s\"" % value
       
    44 
       
    45 def ExtractName(names, default=None):
       
    46     """
       
    47      Extract "name" field from XML entries.
       
    48      @param names : XML entry
       
    49      @default : if it fails to extract from the designated XML entry, return the default value ("None").
       
    50      @return default or the name extracted
       
    51     """
       
    52     if len(names) == 1:
       
    53         return names[0].getcontent()
       
    54     else:
       
    55         for name in names:
       
    56             if name.getLcId() == 1033:
       
    57                 return name.getcontent()
       
    58     return default
       
    59 
       
    60 #--------------------------------------------------
       
    61 #         Remote Exec Etherlab Commands
       
    62 #--------------------------------------------------
       
    63 
       
    64 # --------------------- for master ---------------------------
       
    65 MASTER_STATE = """
       
    66 import commands
       
    67 result = commands.getoutput("ethercat master")
       
    68 returnVal =result 
       
    69 """
       
    70 
       
    71 # --------------------- for slave ----------------------------
       
    72 # ethercat state -p (slave position) (state (INIT, PREOP, SAFEOP, OP))
       
    73 SLAVE_STATE = """
       
    74 import commands
       
    75 result = commands.getoutput("ethercat state -p %d %s")
       
    76 returnVal = result 
       
    77 """
       
    78 
       
    79 # ethercat slave
       
    80 GET_SLAVE = """
       
    81 import commands
       
    82 result = commands.getoutput("ethercat slaves")
       
    83 returnVal =result 
       
    84 """
       
    85 
       
    86 # ethercat xml -p (slave position)
       
    87 SLAVE_XML = """
       
    88 import commands
       
    89 result = commands.getoutput("ethercat xml -p %d")
       
    90 returnVal = result 
       
    91 """
       
    92 
       
    93 # ethercat sdos -p (slave position)
       
    94 SLAVE_SDO = """
       
    95 import commands
       
    96 result = commands.getoutput("ethercat sdos -p %d")
       
    97 returnVal =result 
       
    98 """
       
    99 
       
   100 # ethercat upload -p (slave position) (main index) (sub index)
       
   101 GET_SLOW_SDO = """
       
   102 import commands
       
   103 result = commands.getoutput("ethercat upload -p %d %s %s")
       
   104 returnVal =result 
       
   105 """
       
   106 
       
   107 # ethercat download -p (slave position) (main index) (sub index) (value)
       
   108 SDO_DOWNLOAD = """
       
   109 import commands
       
   110 result = commands.getoutput("ethercat download --type %s -p %d %s %s %s")
       
   111 returnVal =result 
       
   112 """
       
   113 
       
   114 # ethercat sii_read -p (slave position)
       
   115 SII_READ = """
       
   116 import commands
       
   117 result = commands.getoutput("ethercat sii_read -p %d")
       
   118 returnVal =result 
       
   119 """
       
   120 
       
   121 # ethercat reg_read -p (slave position) (address) (size)
       
   122 REG_READ = """
       
   123 import commands
       
   124 result = commands.getoutput("ethercat reg_read -p %d %s %s")
       
   125 returnVal =result 
       
   126 """
       
   127 
       
   128 # ethercat sii_write -p (slave position) - (contents)
       
   129 SII_WRITE = """ 
       
   130 import subprocess 
       
   131 process = subprocess.Popen(
       
   132     ["ethercat", "-f", "sii_write", "-p", "%d", "-"],
       
   133     stdin=subprocess.PIPE)
       
   134 process.communicate(sii_data)
       
   135 returnVal = process.returncode 
       
   136 """
       
   137 
       
   138 # ethercat reg_write -p (slave position) -t (uinit16) (address) (data)
       
   139 REG_WRITE = """ 
       
   140 import commands
       
   141 result = commands.getoutput("ethercat reg_write -p %d -t uint16 %s %s")
       
   142 returnVal =result 
       
   143 """ 
       
   144 
       
   145 # ethercat rescan -p (slave position)
       
   146 RESCAN = """ 
       
   147 import commands
       
   148 result = commands.getoutput("ethercat rescan -p %d")
       
   149 returnVal =result 
       
   150 """
       
   151 
       
   152 #--------------------------------------------------
       
   153 #    Common Method For EtherCAT Management 
       
   154 #--------------------------------------------------
       
   155 class _CommonSlave:
       
   156 
       
   157     # ----- Data Structure for ethercat management ----
       
   158     SlaveState = ""
       
   159 
       
   160     # category of SDO data
       
   161     DatatypeDescription, CommunicationObject, ManufacturerSpecific, \
       
   162     ProfileSpecific, Reserved, AllSDOData = range(6)
       
   163     
       
   164     # store the execution result of "ethercat sdos" command into SaveSDOData.
       
   165     SaveSDOData = []
       
   166     
       
   167     # Flags for checking "write" permission of OD entries 
       
   168     CheckPREOP = False
       
   169     CheckSAFEOP = False
       
   170     CheckOP = False
       
   171 
       
   172     # Save PDO Data
       
   173     TxPDOInfo = []
       
   174     TxPDOCategory = []
       
   175     RxPDOInfo = []
       
   176     RxPDOCategory = []
       
   177     
       
   178     # Save EEPROM Data
       
   179     SiiData = ""
       
   180 
       
   181     # Save Register Data
       
   182     RegData = ""
       
   183     CrtRegSpec = {"ESCType": "",
       
   184                   "FMMUNumber": "",
       
   185                   "SMNumber": "",
       
   186                   "PDIType": ""}
       
   187     
       
   188     def __init__(self, controler):
       
   189         """
       
   190         Constructor
       
   191         @param controler: _EthercatSlaveCTN class in EthercatSlave.py
       
   192         """
       
   193         self.Controler = controler
       
   194          
       
   195         self.ClearSDODataSet()
       
   196     
       
   197     #-------------------------------------------------------------------------------
       
   198     #                        Used Master State
       
   199     #-------------------------------------------------------------------------------
       
   200     def GetMasterState(self):
       
   201         """
       
   202         Execute "ethercat master" command and parse the execution result
       
   203         @return MasterState 
       
   204         """
       
   205 
       
   206         # exectute "ethercat master" command 
       
   207         error, return_val = self.Controler.RemoteExec(MASTER_STATE, return_val = None)
       
   208         master_state = {}
       
   209         # parse the reslut
       
   210         for each_line in return_val.splitlines():
       
   211             if len(each_line) > 0 :
       
   212                 chunks = each_line.strip().split(':', 1)
       
   213                 key = chunks[0]
       
   214                 value = []
       
   215                 if len(chunks) > 1 :
       
   216                     value = chunks[1].split()
       
   217                 if '(attached)' in value:
       
   218                     value.remove('(attached)')
       
   219                 master_state[key] = value
       
   220          
       
   221         return master_state     
       
   222     
       
   223     #-------------------------------------------------------------------------------
       
   224     #                        Used Slave State
       
   225     #-------------------------------------------------------------------------------
       
   226     def RequestSlaveState(self, command):
       
   227         """
       
   228         Set slave state to the specified one using "ethercat states -p %d %s" command.
       
   229         Command example : "ethercat states -p 0 PREOP" (target slave position and target state are given.)
       
   230         @param command : target slave state 
       
   231         """
       
   232         error, return_val = self.Controler.RemoteExec(SLAVE_STATE%(self.Controler.GetSlavePos(), command), return_val = None)
       
   233     
       
   234     def GetSlaveStateFromSlave(self):  
       
   235         """
       
   236         Get slave information using "ethercat slaves" command and store the information into internal data structure 
       
   237         (self.SlaveState) for "Slave State" 
       
   238         return_val example : 0  0:0  PREOP  +  EL9800 (V4.30) (PIC24, SPI, ET1100)
       
   239         """ 
       
   240         error, return_val = self.Controler.RemoteExec(GET_SLAVE, return_val = None)
       
   241         self.SlaveState = return_val
       
   242         return return_val 
       
   243 
       
   244     #-------------------------------------------------------------------------------
       
   245     #                        Used SDO Management
       
   246     #-------------------------------------------------------------------------------
       
   247     def GetSlaveSDOFromSlave(self):
       
   248         """
       
   249         Get SDO objects information of current slave using "ethercat sdos -p %d" command.
       
   250         Command example : "ethercat sdos -p 0"
       
   251         @return return_val : execution results of "ethercat sdos" command (need to be parsed later)
       
   252         """  
       
   253         error, return_val = self.Controler.RemoteExec(SLAVE_SDO%(self.Controler.GetSlavePos()), return_val = None)
       
   254         return return_val   
       
   255         
       
   256     def SDODownload(self, data_type, idx, sub_idx, value):
       
   257         """
       
   258         Set an SDO object value to user-specified value using "ethercat download" command.
       
   259         Command example : "ethercat download --type int32 -p 0 0x8020 0x12 0x00000000"
       
   260         @param data_type : data type of SDO entry
       
   261         @param idx : index of the SDO entry
       
   262         @param sub_idx : subindex of the SDO entry
       
   263         @param value : value of SDO entry
       
   264         """  
       
   265         error, return_val = self.Controler.RemoteExec(SDO_DOWNLOAD%(data_type, self.Controler.GetSlavePos(), idx, sub_idx, value), return_val = None)
       
   266     
       
   267     def BackupSDODataSet(self):
       
   268         """
       
   269         Back-up current SDO entry information to restore the SDO data 
       
   270          in case that the user cancels SDO update operation.
       
   271     	"""  
       
   272         self.BackupDatatypeDescription = self.SaveDatatypeDescription
       
   273         self.BackupCommunicationObject = self.SaveCommunicationObject
       
   274         self.BackupManufacturerSpecific = self.SaveManufacturerSpecific
       
   275         self.BackupProfileSpecific = self.SaveProfileSpecific
       
   276         self.BackupReserved = self.SaveReserved
       
   277         self.BackupAllSDOData = self.SaveAllSDOData
       
   278     
       
   279     def ClearSDODataSet(self):
       
   280         """
       
   281         Clear the specified SDO entry information.
       
   282         """ 
       
   283         for count in range(6):
       
   284             self.SaveSDOData.append([])
       
   285     
       
   286     #-------------------------------------------------------------------------------
       
   287     #                        Used PDO Monitoring
       
   288     #-------------------------------------------------------------------------------
       
   289     def RequestPDOInfo(self):
       
   290         """
       
   291         Load slave information from RootClass (XML data) and parse the information (calling SlavePDOData() method).
       
   292         """ 
       
   293         # Load slave information from ESI XML file (def EthercatMaster.py)
       
   294         slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
       
   295         
       
   296         type_infos = slave.getType()
       
   297         device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
       
   298         # Initialize PDO data set
       
   299         self.ClearDataSet()
       
   300         
       
   301         # if 'device' object is valid, call SavePDOData() to parse PDO data 
       
   302         if device is not None :
       
   303             self.SavePDOData(device)
       
   304     
       
   305     def SavePDOData(self, device):
       
   306         """
       
   307         Parse PDO data and store the results in TXPDOCategory and RXPDOCategory
       
   308         Tx(Rx)PDOCategory : index, name, entry number
       
   309         Tx(Rx)Info : entry index, sub index, name, length, type
       
   310         @param device : Slave information extracted from ESI XML file
       
   311         """ 
       
   312         # Parsing TXPDO entries
       
   313         for pdo, pdo_info in ([(pdo, "Inputs") for pdo in device.getTxPdo()]):
       
   314             # Save pdo_index, entry, and name of each entry
       
   315             pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   316             entries = pdo.getEntry()
       
   317             pdo_name = ExtractName(pdo.getName())
       
   318             
       
   319             # Initialize entry number count
       
   320             count = 0
       
   321             
       
   322             # Parse entries
       
   323             for entry in entries:
       
   324                 # Save index and subindex
       
   325                 index = ExtractHexDecValue(entry.getIndex().getcontent())
       
   326                 subindex = ExtractHexDecValue(entry.getSubIndex())
       
   327                 # if entry name exists, save entry data
       
   328                 if ExtractName(entry.getName()) is not None :
       
   329                     entry_infos = {
       
   330                                 "entry_index" : index,
       
   331                                 "subindex" : subindex,
       
   332                                 "name" : ExtractName(entry.getName()),
       
   333                                 "bitlen" : entry.getBitLen(),
       
   334                                 "type" : entry.getDataType().getcontent()
       
   335                                     }
       
   336                     self.TxPDOInfo.append(entry_infos)
       
   337                     count += 1
       
   338               
       
   339             categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count}  
       
   340             self.TxPDOCategory.append(categorys)
       
   341 
       
   342         # Parsing RxPDO entries
       
   343         for pdo, pdo_info in ([(pdo, "Outputs") for pdo in device.getRxPdo()]):
       
   344             # Save pdo_index, entry, and name of each entry
       
   345             pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
       
   346             entries = pdo.getEntry()
       
   347             pdo_name = ExtractName(pdo.getName())
       
   348             
       
   349             # Initialize entry number count
       
   350             count = 0          
       
   351 
       
   352             # Parse entries          
       
   353             for entry in entries:
       
   354                 # Save index and subindex
       
   355                 index = ExtractHexDecValue(entry.getIndex().getcontent())
       
   356                 subindex = ExtractHexDecValue(entry.getSubIndex())
       
   357                 # if entry name exists, save entry data
       
   358                 if ExtractName(entry.getName()) is not None :
       
   359                     entry_infos = {
       
   360                                 "entry_index" : index,
       
   361                                 "subindex" : subindex,
       
   362                                 "name" : ExtractName(entry.getName()),
       
   363                                 "bitlen" : str(entry.getBitLen()),
       
   364                                 "type" : entry.getDataType().getcontent()
       
   365                                     }
       
   366                     self.RxPDOInfo.append(entry_infos)
       
   367                     count += 1
       
   368     
       
   369             categorys = {"pdo_index" : pdo_index, "name" : pdo_name, "number_of_entry" : count}  
       
   370             self.RxPDOCategory.append(categorys) 
       
   371 
       
   372     def GetTxPDOCategory(self):
       
   373         """
       
   374         Get TxPDOCategory data structure (Meta informaton of TxPDO).
       
   375         TxPDOCategorys : index, name, number of entries
       
   376         @return TxPDOCategorys
       
   377         """ 
       
   378         return self.TxPDOCategory
       
   379         
       
   380     def GetRxPDOCategory(self):
       
   381         """
       
   382         Get RxPDOCategory data structure (Meta information of RxPDO).
       
   383         RxPDOCategorys : index, name, number of entries
       
   384         @return RxPDOCategorys
       
   385         """ 
       
   386         return self.RxPDOCategory
       
   387         
       
   388     def GetTxPDOInfo(self):
       
   389         """
       
   390         Get TxPDOInfo data structure (Detailed information on TxPDO entries). 
       
   391         TxPDOInfos : entry index, sub index, name, length, type
       
   392         @return TxPDOInfos
       
   393         """ 
       
   394         return self.TxPDOInfo
       
   395         
       
   396     def GetRxPDOInfo(self):
       
   397         """
       
   398         Get RxPDOInfo data structure (Detailed information on RxPDO entries). 
       
   399         RxPDOInfos : entry index, sub index, name, length, type
       
   400         @return RxPDOInfos
       
   401         """ 
       
   402         return self.RxPDOInfo
       
   403         
       
   404     def ClearDataSet(self):
       
   405         """
       
   406         Initialize PDO management data structure.
       
   407         """ 
       
   408         self.TxPDOInfos = []
       
   409         self.TxPDOCategorys = []
       
   410         self.RxPDOInfos = []
       
   411         self.RxPDOCategorys = []
       
   412                
       
   413     #-------------------------------------------------------------------------------
       
   414     #                        Used EEPROM Management
       
   415     #-------------------------------------------------------------------------------
       
   416     # Base data types in ETG2000; format = {"Name": "BitSize"}
       
   417     BaseDataTypeDict = {"BOOL": "01",
       
   418                         "SINT": "02",
       
   419                         "INT": "03",
       
   420                         "DINT": "04",
       
   421                         "USINT": "05",
       
   422                         "UINT": "06",
       
   423                         "UDINT": "07",
       
   424                         "REAL": "08",
       
   425                         "INT24": "10",
       
   426                         "LREAL": "11",
       
   427                         "INT40": "12",
       
   428                         "INT48": "13",
       
   429                         "INT56": "14",
       
   430                         "LINT": "15",
       
   431                         "UINT24": "16",
       
   432                         "UINT40": "18",
       
   433                         "UINT48": "19",
       
   434                         "UINT56": "1a",
       
   435                         "ULINT": "1b",
       
   436                         "USINT": "1e",
       
   437                         "BITARR8": "2d",
       
   438                         "BITARR16": "2e",
       
   439                         "BITARR32": "2f",
       
   440                         "BIT1": "30",
       
   441                         "BIT2": "31",
       
   442                         "BIT3": "32",
       
   443                         "BIT4": "33",
       
   444                         "BIT5": "34",
       
   445                         "BIT6": "35",
       
   446                         "BIT7": "36",
       
   447                         "BIT8": "37"}        
       
   448         
       
   449     def GetSmartViewInfos(self):
       
   450         """
       
   451         Parse XML data for "Smart View" of EEPROM contents.
       
   452         @return smartview_infos : EEPROM contents dictionary
       
   453         """ 
       
   454 
       
   455         smartview_infos = {"eeprom_size": 128,
       
   456                            "pdi_type": 0,
       
   457                            "device_emulation": "False",
       
   458                            "vendor_id": '0x00000000',
       
   459                            "product_code": '0x00000000',
       
   460                            "revision_no": '0x00000000',
       
   461                            "serial_no": '0x00000000',
       
   462                            "supported_mailbox": "",
       
   463                            "mailbox_bootstrapconf_outstart": '0',
       
   464                            "mailbox_bootstrapconf_outlength": '0',
       
   465                            "mailbox_bootstrapconf_instart": '0',
       
   466                            "mailbox_bootstrapconf_inlength": '0',
       
   467                            "mailbox_standardconf_outstart": '0',
       
   468                            "mailbox_standardconf_outlength": '0',
       
   469                            "mailbox_standardconf_instart": '0',
       
   470                            "mailbox_standardconf_inlength": '0'}
       
   471         
       
   472         slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
       
   473         type_infos = slave.getType()
       
   474         device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
       
   475 
       
   476         # 'device' represents current slave device selected by user
       
   477         if device is not None:
       
   478             for eeprom_element in device.getEeprom().getcontent()["value"]:
       
   479                 # get EEPROM size; <Device>-<Eeprom>-<ByteSize>
       
   480                 if eeprom_element["name"] == "ByteSize":
       
   481                     smartview_infos["eeprom_size"] = eeprom_element["value"]
       
   482                         
       
   483                 elif eeprom_element["name"] == "ConfigData":
       
   484                     configData_data = self.DecimalToHex(eeprom_element["value"])
       
   485                     # get PDI type; <Device>-<Eeprom>-<ConfigData> address 0x00
       
   486                     smartview_infos["pdi_type"] = int(configData_data[0:2], 16)
       
   487                     # get state of device emulation; <Device>-<Eeprom>-<ConfigData> address 0x01
       
   488                     if "{:0>8b}".format(int(configData_data[2:4], 16))[7] == '1':
       
   489                         smartview_infos["device_emulation"] = "True"
       
   490 
       
   491                 elif eeprom_element["name"] == "BootStrap":
       
   492                     bootstrap_data = "{:0>16x}".format(eeprom_element["value"])
       
   493                     # get bootstrap configuration; <Device>-<Eeprom>-<BootStrap>
       
   494                     for cfg, iter in [("mailbox_bootstrapconf_outstart", 0), 
       
   495                                       ("mailbox_bootstrapconf_outlength", 1),
       
   496                                       ("mailbox_bootstrapconf_instart", 2),
       
   497                                       ("mailbox_bootstrapconf_inlength", 3)]:
       
   498                         smartview_infos[cfg] = str(int(bootstrap_data[4*iter+2:4*(iter+1)]+bootstrap_data[4*iter:4*iter+2], 16))
       
   499             
       
   500             # get protocol (profile) types supported by mailbox; <Device>-<Mailbox>
       
   501             for mailbox_protocol in ["VoE", "SoE", "FoE", "CoE", "EoE", "AoE"]:
       
   502                 if eval("device.getMailbox().get%s()"%mailbox_protocol) is not None:
       
   503                     smartview_infos["supported_mailbox"] += "%s,  "%mailbox_protocol
       
   504             smartview_infos["supported_mailbox"] = smartview_infos["supported_mailbox"].strip(",  ")
       
   505                 
       
   506             # get standard configuration of mailbox; <Device>-<Sm>
       
   507             for sm_element in device.getSm():
       
   508                 if sm_element.getcontent() == "MBoxOut":
       
   509                     smartview_infos["mailbox_standardconf_outstart"] = str(ExtractHexDecValue(sm_element.getStartAddress()))
       
   510                     smartview_infos["mailbox_standardconf_outlength"] = str(ExtractHexDecValue(sm_element.getDefaultSize()))
       
   511                 elif sm_element.getcontent() == "MBoxIn":
       
   512                     smartview_infos["mailbox_standardconf_instart"] = str(ExtractHexDecValue(sm_element.getStartAddress()))
       
   513                     smartview_infos["mailbox_standardconf_inlength"] = str(ExtractHexDecValue(sm_element.getDefaultSize()))
       
   514                 else:
       
   515                     pass
       
   516 
       
   517             # get device identity from <Device>-<Type>
       
   518             #  vendor ID; by default, pre-defined value in self.ModulesLibrary
       
   519             #             if device type in 'vendor' item equals to actual slave device type, set 'vendor_id' to vendor ID.
       
   520             for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
   521                 for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]:
       
   522                     if available_device[0] == type_infos["device_type"]:
       
   523                         smartview_infos["vendor_id"] = "0x" + "{:0>8x}".format(vendor_id)
       
   524                         
       
   525             #  product code; 
       
   526             if device.getType().getProductCode() is not None:
       
   527                 product_code = device.getType().getProductCode()
       
   528                 smartview_infos["product_code"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(product_code))
       
   529                 
       
   530             #  revision number; 
       
   531             if device.getType().getRevisionNo() is not None:
       
   532                 revision_no = device.getType().getRevisionNo()
       
   533                 smartview_infos["revision_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(revision_no))
       
   534                 
       
   535             #  serial number;
       
   536             if device.getType().getSerialNo() is not None:
       
   537                 serial_no = device.getType().getSerialNo()
       
   538                 smartview_infos["serial_no"] = "0x"+"{:0>8x}".format(ExtractHexDecValue(serial_no))
       
   539                                             
       
   540             return smartview_infos
       
   541         
       
   542         else:
       
   543             return None
       
   544         
       
   545     def DecimalToHex(self, decnum):
       
   546         """
       
   547         Convert decimal value into hexadecimal representation. 
       
   548         @param decnum : decimal value
       
   549         @return hex_data : hexadecimal representation of input value in decimal
       
   550         """ 
       
   551         value = "%x" % decnum
       
   552         value_len = len(value)
       
   553         if (value_len % 2) == 0:
       
   554             hex_len = value_len
       
   555         else:
       
   556             hex_len = (value_len / 2) * 2 + 2
       
   557         
       
   558         hex_data = ("{:0>"+str(hex_len)+"x}").format(decnum)
       
   559         
       
   560         return hex_data
       
   561 
       
   562     def SiiRead(self):
       
   563         """
       
   564         Get slave EEPROM contents maintained by master device using "ethercat sii_read -p %d" command.
       
   565         Command example : "ethercat sii_read -p 0"
       
   566         @return return_val : result of "ethercat sii_read" (binary data)
       
   567         """ 
       
   568         error, return_val = self.Controler.RemoteExec(SII_READ%(self.Controler.GetSlavePos()), return_val = None)
       
   569         self.SiiData = return_val
       
   570         return return_val
       
   571 
       
   572     def SiiWrite(self, binary):
       
   573         """
       
   574         Overwrite slave EEPROM contents using "ethercat sii_write -p %d" command.
       
   575         Command example : "ethercat sii_write -p 0 - (binary contents)"
       
   576         @param binary : EEPROM contents in binary data format
       
   577         @return return_val : result of "ethercat sii_write" (If it succeeds, the return value is NULL.)
       
   578         """ 
       
   579         error, return_val = self.Controler.RemoteExec(SII_WRITE%(self.Controler.GetSlavePos()), return_val = None, sii_data = binary)
       
   580         return return_val 
       
   581 
       
   582     def LoadData(self):
       
   583         """
       
   584         Loading data from EEPROM use Sii_Read Method
       
   585         @return self.BinaryCode : slave EEPROM data in binary format (zero-padded)
       
   586         """ 
       
   587         return_val = self.Controler.CommonMethod.SiiRead()
       
   588         self.BinaryCode = return_val
       
   589         self.Controler.SiiData = self.BinaryCode
       
   590 
       
   591         # append zero-filled padding data up to EEPROM size
       
   592         for index in range(self.SmartViewInfosFromXML["eeprom_size"] - len(self.BinaryCode)):
       
   593             self.BinaryCode = self.BinaryCode +'ff'.decode('hex')
       
   594               
       
   595         return self.BinaryCode
       
   596 
       
   597     def HexRead(self, binary):
       
   598         """
       
   599         Convert binary digit representation into hexadecimal representation for "Hex View" menu.
       
   600         @param binary : binary digits
       
   601         @return hexCode : hexadecimal digits
       
   602         @return hexview_table_row, hexview_table_col : Grid size for "Hex View" UI
       
   603         """ 
       
   604         row_code = []
       
   605         row_text = ""
       
   606         row = 0
       
   607         hex_code = []
       
   608 
       
   609         hexview_table_col = 17
       
   610         
       
   611         for index in range(0, len(binary)) :
       
   612             if len(binary[index]) != 1:
       
   613                 break
       
   614             else:
       
   615                 digithexstr = hex(ord(binary[index])) 
       
   616 
       
   617                 tempvar2 = digithexstr[2:4]
       
   618                 if len(tempvar2) == 1:
       
   619                     tempvar2 = "0" + tempvar2
       
   620                 row_code.append(tempvar2) 
       
   621                 
       
   622                 if int(digithexstr, 16)>=32 and int(digithexstr, 16)<=126:
       
   623                     row_text = row_text + chr(int(digithexstr, 16))
       
   624                 else:
       
   625                     row_text = row_text + "."
       
   626                 
       
   627                 if index != 0 : 
       
   628                     if len(row_code) == (hexview_table_col - 1):
       
   629                         row_code.append(row_text)
       
   630                         hex_code.append(row_code)
       
   631                         row_text = ""
       
   632                         row_code = []
       
   633                         row = row + 1        
       
   634                                         
       
   635         hexview_table_row = row
       
   636         
       
   637         return hex_code, hexview_table_row, hexview_table_col
       
   638     
       
   639     def GenerateEEPROMList(self, data, direction, length):
       
   640         """
       
   641         Generate EEPROM data list by reconstructing 'data' string.
       
   642         example : data="12345678", direction=0, length=8 -> eeprom_list=['12', '34', '56', '78']
       
   643                   data="12345678", direction=1, length=8 -> eeprom_list=['78', '56', '34', '12']
       
   644         @param data : string to be reconstructed
       
   645         @param direction : endianness
       
   646         @param length : data length
       
   647         @return eeprom_list : reconstructed list data structure
       
   648         """ 
       
   649         eeprom_list = []
       
   650 
       
   651         if direction is 0 or 1:
       
   652             for i in range(length/2):
       
   653                 if data == "":
       
   654                     eeprom_list.append("00")
       
   655                 else:
       
   656                     eeprom_list.append(data[direction*(length-2):direction*(length-2)+2])
       
   657                 data = data[(1-direction)*2:length-direction*2]
       
   658                 length -= 2
       
   659         return eeprom_list
       
   660     
       
   661     def XmlToEeprom(self):
       
   662         """
       
   663         Extract slave EEPROM contents using slave ESI XML file.
       
   664           - Mandatory parts
       
   665           - String category : ExtractEEPROMStringCategory()
       
   666           - General category : ExtractEEPROMGeneralCategory()
       
   667           - FMMU category : ExtractEEPROMFMMUCategory
       
   668           - SyncM category : ExtractEEPROMSyncMCategory()
       
   669           - Tx/RxPDO category : ExtractEEPROMPDOCategory()
       
   670           - DC category : ExtractEEPROMDCCategory()
       
   671         @return eeprom_binary 
       
   672         """ 
       
   673         eeprom = []
       
   674         data = ""
       
   675         eeprom_size = 0
       
   676         eeprom_binary = ""
       
   677 
       
   678         # 'device' is the slave device of the current EtherCAT slave plugin
       
   679         slave = self.Controler.CTNParent.GetSlave(self.Controler.GetSlavePos())
       
   680         type_infos = slave.getType()
       
   681         device, alignment = self.Controler.CTNParent.GetModuleInfos(type_infos)
       
   682         
       
   683         if device is not None:
       
   684             # get ConfigData for EEPROM offset 0x0000-0x000d; <Device>-<Eeprom>-<ConfigData>
       
   685             for eeprom_element in device.getEeprom().getcontent()["value"]:
       
   686                 if eeprom_element["name"] == "ConfigData":
       
   687                     data = self.DecimalToHex(eeprom_element["value"])
       
   688             eeprom += self.GenerateEEPROMList(data, 0, 28)
       
   689             
       
   690             # calculate CRC for EEPROM offset 0x000e-0x000f
       
   691             crc = 0x48
       
   692             for segment in eeprom:
       
   693                 for i in range(8):
       
   694                     bit = crc & 0x80
       
   695                     crc = (crc << 1) | ((int(segment, 16) >> (7 - i)) & 0x01)
       
   696                     if bit:
       
   697                         crc ^= 0x07   
       
   698             for k in range(8):
       
   699                 bit = crc & 0x80
       
   700                 crc <<= 1
       
   701                 if bit:
       
   702                     crc ^= 0x07      
       
   703             eeprom.append(hex(crc)[len(hex(crc))-3:len(hex(crc))-1])
       
   704             eeprom.append("00")
       
   705             
       
   706             # get VendorID for EEPROM offset 0x0010-0x0013;
       
   707             data = ""
       
   708             for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
   709                 for available_device in vendor["groups"][vendor["groups"].keys()[0]]["devices"]:
       
   710                     if available_device[0] == type_infos["device_type"]:
       
   711                         data = "{:0>8x}".format(vendor_id)
       
   712             eeprom += self.GenerateEEPROMList(data, 1, 8)
       
   713             
       
   714             # get Product Code for EEPROM offset 0x0014-0x0017;
       
   715             data = ""
       
   716             if device.getType().getProductCode() is not None:
       
   717                 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getProductCode()))
       
   718             eeprom += self.GenerateEEPROMList(data, 1, 8)
       
   719             
       
   720             # get Revision Number for EEPROM offset 0x0018-0x001b;
       
   721             data = ""
       
   722             if device.getType().getRevisionNo() is not None:
       
   723                 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getRevisionNo()))
       
   724             eeprom += self.GenerateEEPROMList(data, 1, 8)  
       
   725             
       
   726             # get Serial Number for EEPROM 0x001c-0x001f;
       
   727             data = ""
       
   728             if device.getType().getSerialNo() is not None:
       
   729                 data = "{:0>8x}".format(ExtractHexDecValue(device.getType().getSerialNo()))
       
   730             eeprom += self.GenerateEEPROMList(data, 1, 8)
       
   731                 
       
   732             # get Execution Delay for EEPROM 0x0020-0x0021; not analyzed yet
       
   733             eeprom.append("00")
       
   734             eeprom.append("00")
       
   735             
       
   736             # get Port0/1 Delay for EEPROM offset 0x0022-0x0025; not analyzed yet
       
   737             eeprom.append("00")
       
   738             eeprom.append("00")
       
   739             eeprom.append("00")
       
   740             eeprom.append("00")
       
   741             
       
   742             # reserved for EEPROM offset 0x0026-0x0027;
       
   743             eeprom.append("00")
       
   744             eeprom.append("00")
       
   745 
       
   746             # get BootStrap for EEPROM offset 0x0028-0x002e; <Device>-<Eeprom>-<BootStrap>
       
   747             data = ""
       
   748             for eeprom_element in device.getEeprom().getcontent()["value"]:
       
   749                 if eeprom_element["name"] == "BootStrap":
       
   750                     data = "{:0>16x}".format(eeprom_element["value"])
       
   751             eeprom += self.GenerateEEPROMList(data, 0, 16)
       
   752             
       
   753             # get Standard Mailbox for EEPROM offset 0x0030-0x0037; <Device>-<sm>
       
   754             data = ""
       
   755             for sm_element in device.getSm():
       
   756                 if sm_element.getcontent() == "MBoxOut":
       
   757                     standard_receive_mailbox_offset = "{:0>4x}".format(ExtractHexDecValue(sm_element.getStartAddress()))
       
   758                     standard_receive_mailbox_size = "{:0>4x}".format(ExtractHexDecValue(sm_element.getDefaultSize()))
       
   759                 elif sm_element.getcontent() == "MBoxIn":
       
   760                     standard_send_mailbox_offset = "{:0>4x}".format(ExtractHexDecValue(sm_element.getStartAddress()))
       
   761                     standard_send_mailbox_size = "{:0>4x}".format(ExtractHexDecValue(sm_element.getDefaultSize()))
       
   762                     
       
   763             if standard_receive_mailbox_offset is None:
       
   764                 eeprom.append("00")
       
   765                 eeprom.append("00")
       
   766             else:
       
   767                 eeprom.append(standard_receive_mailbox_offset[2:4])
       
   768                 eeprom.append(standard_receive_mailbox_offset[0:2])
       
   769             if standard_receive_mailbox_size is None:
       
   770                 eeprom.append("00")
       
   771                 eeprom.append("00")
       
   772             else:
       
   773                 eeprom.append(standard_receive_mailbox_size[2:4])
       
   774                 eeprom.append(standard_receive_mailbox_size[0:2])
       
   775             if standard_send_mailbox_offset is None:
       
   776                 eeprom.append("00")
       
   777                 eeprom.append("00")
       
   778             else:
       
   779                 eeprom.append(standard_send_mailbox_offset[2:4])
       
   780                 eeprom.append(standard_send_mailbox_offset[0:2])
       
   781             if standard_send_mailbox_size is None:
       
   782                 eeprom.append("00")
       
   783                 eeprom.append("00")
       
   784             else:
       
   785                 eeprom.append(standard_send_mailbox_size[2:4])
       
   786                 eeprom.append(standard_send_mailbox_size[0:2])
       
   787             
       
   788             # get supported mailbox protocols for EEPROM offset 0x0038-0x0039;
       
   789             data = 0
       
   790             for mbox, bit in [(device.getMailbox().getAoE(), 0),
       
   791                               (device.getMailbox().getEoE(), 1),
       
   792                               (device.getMailbox().getCoE(), 2),
       
   793                               (device.getMailbox().getFoE(), 3),
       
   794                               (device.getMailbox().getSoE(), 4),
       
   795                               (device.getMailbox().getVoE(), 5)]:
       
   796                 if mbox is not None:
       
   797                     data += 1<<bit
       
   798             data = "{:0>4x}".format(data)
       
   799             eeprom.append(data[2:4])
       
   800             eeprom.append(data[0:2])
       
   801             
       
   802             # resereved for EEPROM offset 0x003a-0x007b;
       
   803             for i in range(0x007b-0x003a+0x0001):
       
   804                 eeprom.append("00")
       
   805             
       
   806             # get EEPROM size for EEPROM offset 0x007c-0x007d;
       
   807             data = ""
       
   808             for eeprom_element in device.getEeprom().getcontent()["value"]:
       
   809                 if eeprom_element["name"] == "ByteSize":
       
   810                     eeprom_size = int(str(eeprom_element["value"]))
       
   811                     data = "{:0>4x}".format(int(eeprom_element["value"])/1024*8-1)
       
   812 
       
   813             if data == "":
       
   814                 eeprom.append("00")
       
   815                 eeprom.append("00")
       
   816             else:
       
   817                 eeprom.append(data[2:4])
       
   818                 eeprom.append(data[0:2])
       
   819                 
       
   820             # Version for EEPROM 0x007e-0x007f; 
       
   821             #  According to "EtherCAT Slave Device Description(V0.3.0)"
       
   822             eeprom.append("01")
       
   823             eeprom.append("00")
       
   824             
       
   825             # append String Category data
       
   826             for data in self.ExtractEEPROMStringCategory(device):
       
   827                 eeprom.append(data)
       
   828                 
       
   829             # append General Category data
       
   830             for data in self.ExtractEEPROMGeneralCategory(device):
       
   831                 eeprom.append(data)
       
   832                 
       
   833             # append FMMU Category data
       
   834             for data in self.ExtractEEPROMFMMUCategory(device):
       
   835                 eeprom.append(data)
       
   836             
       
   837             # append SyncM Category data
       
   838             for data in self.ExtractEEPROMSyncMCategory(device):
       
   839                 eeprom.append(data)
       
   840                 
       
   841             # append TxPDO Category data
       
   842             for data in self.ExtractEEPROMPDOCategory(device, "TxPdo"):
       
   843                 eeprom.append(data)
       
   844                 
       
   845             # append RxPDO Category data
       
   846             for data in self.ExtractEEPROMPDOCategory(device, "RxPdo"):
       
   847                 eeprom.append(data)
       
   848                 
       
   849             # append DC Category data
       
   850             for data in self.ExtractEEPROMDCCategory(device):
       
   851                 eeprom.append(data)
       
   852             
       
   853             # append padding
       
   854             padding = eeprom_size-len(eeprom)
       
   855             for i in range(padding):
       
   856                 eeprom.append("ff")
       
   857             
       
   858             # convert binary code
       
   859             for index in range(eeprom_size):
       
   860                 eeprom_binary = eeprom_binary + eeprom[index].decode('hex')
       
   861             
       
   862             return eeprom_binary
       
   863     
       
   864     def ExtractEEPROMStringCategory(self, device):
       
   865         """
       
   866         Extract "Strings" category data from slave ESI XML and generate EEPROM image data.
       
   867         @param device : 'device' object in the slave ESI XML
       
   868         @return eeprom : "Strings" category EEPROM image data
       
   869         """ 
       
   870         eeprom = []
       
   871         self.Strings = []
       
   872         data = "" 
       
   873         count = 0 # string counter
       
   874         padflag = False # padding flag if category length is odd
       
   875         
       
   876         # index information for General Category in EEPROM
       
   877         self.GroupIdx = 0
       
   878         self.ImgIdx = 0
       
   879         self.OrderIdx = 0
       
   880         self.NameIdx = 0
       
   881         
       
   882         # flag for preventing duplicated vendor specific data 
       
   883         typeflag = False
       
   884         grouptypeflag = False
       
   885         groupnameflag = False
       
   886         devnameflag = False
       
   887         imageflag = False
       
   888         
       
   889         # vendor specific data
       
   890         #   element1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Type>
       
   891         #   vendor_specific_data : vendor specific data (binary type)
       
   892         vendor_specific_data = ""
       
   893         #   vendor_spec_strings : list of vendor specific "strings" for preventing duplicated strings
       
   894         vendor_spec_strings = []
       
   895         for element in device.getType().getcontent():
       
   896             data += element
       
   897         if data is not "" and type(data) == unicode:
       
   898             for vendor_spec_string in vendor_spec_strings: 
       
   899                 if data == vendor_spec_string:
       
   900                     self.OrderIdx = vendor_spec_strings.index(data)+1
       
   901                     typeflag = True
       
   902                     break
       
   903             if typeflag is False:
       
   904                 count += 1
       
   905                 self.Strings.append(data)
       
   906                 vendor_spec_strings.append(data)
       
   907                 typeflag = True
       
   908                 self.OrderIdx = count
       
   909                 vendor_specific_data += "{:0>2x}".format(len(data))
       
   910                 for character in range(len(data)):
       
   911                     vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   912         data = ""
       
   913         
       
   914         #  element2-1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<GroupType>
       
   915         data = device.getGroupType()
       
   916         if data is not None and type(data) == unicode:
       
   917             for vendor_spec_string in vendor_spec_strings:
       
   918                 if data == vendor_spec_string:
       
   919                     self.GroupIdx = vendor_spec_strings.index(data)+1
       
   920                     grouptypeflag = True
       
   921                     break
       
   922             if grouptypeflag is False:
       
   923                 grouptype = data
       
   924                 count += 1
       
   925                 self.Strings.append(data)
       
   926                 vendor_spec_strings.append(data)
       
   927                 grouptypeflag = True
       
   928                 self.GroupIdx = count
       
   929                 vendor_specific_data += "{:0>2x}".format(len(data))
       
   930                 for character in range(len(data)):
       
   931                     vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   932         
       
   933         #  element2-2; <EtherCATInfo>-<Groups>-<Group>-<Type>            
       
   934         if grouptypeflag is False: 
       
   935             if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
       
   936                 for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
   937                     for group_type, group_etc in vendor["groups"].iteritems():
       
   938                         for device_item in group_etc["devices"]:
       
   939                             if device == device_item[1]: 
       
   940                                 data = group_type
       
   941                 if data is not None and type(data) == unicode:
       
   942                     for vendor_spec_string in vendor_spec_strings:
       
   943                         if data == vendor_spec_string:
       
   944                             self.GroupIdx = vendor_spec_strings.index(data)+1
       
   945                             grouptypeflag = True
       
   946                             break
       
   947                     if grouptypeflag is False:
       
   948                         grouptype = data
       
   949                         count += 1
       
   950                         self.Strings.append(data)
       
   951                         vendor_spec_strings.append(data)
       
   952                         grouptypeflag = True
       
   953                         self.GroupIdx = count
       
   954                         vendor_specific_data += "{:0>2x}".format(len(data))
       
   955                         for character in range(len(data)):
       
   956                             vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   957         data = ""
       
   958         
       
   959         #  element3; <EtherCATInfo>-<Descriptions>-<Groups>-<Group>-<Name(LcId is "1033")>
       
   960         if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
       
   961             for vendorId, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
   962                 for group_type, group_etc in vendor["groups"].iteritems():
       
   963                     for device_item in group_etc["devices"]:
       
   964                         if device == device_item[1]:
       
   965                             data = group_etc["name"]
       
   966         if data is not "" and type(data) == unicode:
       
   967             for vendor_spec_string in vendor_spec_strings:
       
   968                 if data == vendor_spec_string:
       
   969                     groupnameflag = True
       
   970                     break
       
   971             if groupnameflag is False:
       
   972                 count += 1
       
   973                 self.Strings.append(data)
       
   974                 vendor_spec_strings.append(data)
       
   975                 groupnameflag = True
       
   976                 vendor_specific_data += "{:0>2x}".format(len(data))
       
   977                 for character in range(len(data)):
       
   978                     vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
   979         data = ""
       
   980         
       
   981         #  element4; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Name(LcId is "1033" or "1"?)>
       
   982         for element in device.getName():
       
   983             if element.getLcId() == 1 or element.getLcId()==1033:
       
   984                 data = element.getcontent()
       
   985         if data is not "" and type(data) == unicode:
       
   986             for vendor_spec_string in vendor_spec_strings:
       
   987                 if data == vendor_spec_string:
       
   988                     self.NameIdx = vendor_spec_strings.index(data)+1
       
   989                     devnameflag = True
       
   990                     break
       
   991             if devnameflag is False:
       
   992                 count += 1
       
   993                 self.Strings.append(data)
       
   994                 vendor_spec_strings.append(data)
       
   995                 devnameflag = True
       
   996                 self.NameIdx = count
       
   997                 vendor_specific_data += "{:0>2x}".format(len(data))
       
   998                 for character in range(len(data)):
       
   999                     vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
  1000         data = ""
       
  1001         
       
  1002         #  element5-1; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Image16x14>
       
  1003         if device.getcontent() is not None:
       
  1004             data = device.getcontent()["value"]
       
  1005             if data is not None and type(data) == unicode:
       
  1006                 for vendor_spec_string in vendor_spec_strings:
       
  1007                     if data == vendor_spec_string:
       
  1008                         self.ImgIdx = vendor_spec_strings.index(data)+1
       
  1009                         imageflag = True
       
  1010                         break
       
  1011                 if imageflag is False:
       
  1012                     count += 1
       
  1013                     self.Strings.append(data)
       
  1014                     vendor_spec_strings.append(data)
       
  1015                     imageflag = True
       
  1016                     self.ImgIdx = count
       
  1017                     vendor_specific_data += "{:0>2x}".format(len(data))
       
  1018                     for character in range(len(data)):
       
  1019                         vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
  1020                         
       
  1021         #  element5-2; <EtherCATInfo>-<Descriptions>-<Groups>-<Group>-<Image16x14>
       
  1022         if imageflag is False:
       
  1023             if self.Controler.CTNParent.CTNParent.ModulesLibrary.Library is not None:
       
  1024                 for vendor_id, vendor in self.Controler.CTNParent.CTNParent.ModulesLibrary.Library.iteritems():
       
  1025                     for group_type, group_etc in vendor["groups"].iteritems():
       
  1026                         for device_item in group_etc["devices"]:
       
  1027                             if device == device_item[1]:
       
  1028                                 data = group_etc["value"]
       
  1029                 if data is not None and type(data) == unicode:
       
  1030                     for vendor_spec_string in vendor_spec_strings:
       
  1031                         if data == vendor_spec_string:
       
  1032                             self.ImgIdx = vendor_spec_strings.index(data)+1
       
  1033                             imageflag = True
       
  1034                             break
       
  1035                     if imageflag is False:
       
  1036                         count += 1
       
  1037                         self.Strings.append(data)
       
  1038                         vendor_spec_strings.append(data)
       
  1039                         imageflag = True
       
  1040                         self.ImgIdx = count
       
  1041                         vendor_specific_data += "{:0>2x}".format(len(data))
       
  1042                         for character in range(len(data)):
       
  1043                             vendor_specific_data += "{:0>2x}".format(ord(data[character]))
       
  1044         data = ""
       
  1045         
       
  1046         # DC related elements
       
  1047         #  <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Dc>-<OpMode>-<Name>
       
  1048         dc_related_elements = ""
       
  1049         if device.getDc() is not None:
       
  1050             for element in device.getDc().getOpMode():
       
  1051                 data = element.getName()
       
  1052                 if data is not "":
       
  1053                     count += 1
       
  1054                     self.Strings.append(data)
       
  1055                     dc_related_elements += "{:0>2x}".format(len(data))
       
  1056                     for character in range(len(data)):
       
  1057                         dc_related_elements += "{:0>2x}".format(ord(data[character]))
       
  1058                     data = ""
       
  1059         
       
  1060         # Input elements(TxPDO)
       
  1061         #  <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<TxPdo>; Name
       
  1062         input_elements = ""
       
  1063         inputs = []
       
  1064         for element in device.getTxPdo():
       
  1065             for name in element.getName():
       
  1066                 data = name.getcontent()
       
  1067             for input in inputs:
       
  1068                 if data == input: 
       
  1069                     data = ""
       
  1070             if data is not "":
       
  1071                 count += 1
       
  1072                 self.Strings.append(data)
       
  1073                 inputs.append(data)
       
  1074                 input_elements += "{:0>2x}".format(len(data))
       
  1075                 for character in range(len(data)):
       
  1076                     input_elements += "{:0>2x}".format(ord(data[character]))
       
  1077                 data = ""            
       
  1078             for entry in element.getEntry():
       
  1079                 for name in entry.getName():
       
  1080                     data = name.getcontent()
       
  1081                 for input in inputs:
       
  1082                     if data == input: 
       
  1083                         data = ""
       
  1084                 if data is not "":
       
  1085                     count += 1
       
  1086                     self.Strings.append(data)
       
  1087                     inputs.append(data)
       
  1088                     input_elements += "{:0>2x}".format(len(data))
       
  1089                     for character in range(len(data)):
       
  1090                         input_elements += "{:0>2x}".format(ord(data[character]))
       
  1091                     data = ""
       
  1092         
       
  1093         # Output elements(RxPDO)
       
  1094         #  <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<RxPdo>; Name
       
  1095         output_elements = ""
       
  1096         outputs = []
       
  1097         for element in device.getRxPdo():
       
  1098             for name in element.getName():
       
  1099                 data = name.getcontent()
       
  1100             for output in outputs:
       
  1101                 if data == output: 
       
  1102                     data = ""
       
  1103             if data is not "":
       
  1104                 count += 1
       
  1105                 self.Strings.append(data)
       
  1106                 outputs.append(data)
       
  1107                 output_elements += "{:0>2x}".format(len(data))
       
  1108                 for character in range(len(data)):
       
  1109                     output_elements += "{:0>2x}".format(ord(data[character]))
       
  1110                 data = ""            
       
  1111             for entry in element.getEntry():
       
  1112                 for name in entry.getName():
       
  1113                     data = name.getcontent()
       
  1114                 for output in outputs:
       
  1115                     if data == output: 
       
  1116                         data = ""
       
  1117                 if data is not "":
       
  1118                     count += 1
       
  1119                     self.Strings.append(data)
       
  1120                     outputs.append(data)
       
  1121                     output_elements += "{:0>2x}".format(len(data))
       
  1122                     for character in range(len(data)):
       
  1123                         output_elements += "{:0>2x}".format(ord(data[character]))
       
  1124                     data = ""     
       
  1125         
       
  1126         # form eeprom data
       
  1127         #  category header
       
  1128         eeprom.append("0a")
       
  1129         eeprom.append("00")
       
  1130         #  category length (word); 1 word is 4 bytes. "+2" is the length of string's total number
       
  1131         length = len(vendor_specific_data + dc_related_elements + input_elements + output_elements) + 2
       
  1132         if length%4 == 0:
       
  1133             pass
       
  1134         else:
       
  1135             length +=length%4
       
  1136             padflag = True
       
  1137         eeprom.append("{:0>4x}".format(length/4)[2:4])
       
  1138         eeprom.append("{:0>4x}".format(length/4)[0:2])
       
  1139         #  total numbers of strings
       
  1140         eeprom.append("{:0>2x}".format(count))
       
  1141         for element in [vendor_specific_data,
       
  1142                         dc_related_elements,
       
  1143                         input_elements,
       
  1144                         output_elements]:
       
  1145             for iter in range(len(element)/2):
       
  1146                 if element == "":
       
  1147                     eeprom.append("00")
       
  1148                 else:
       
  1149                     eeprom.append(element[0:2])
       
  1150                 element = element[2:len(element)]     
       
  1151         # padding if length is odd bytes 
       
  1152         if padflag is True:
       
  1153             eeprom.append("ff")
       
  1154         
       
  1155         return eeprom
       
  1156     
       
  1157     def ExtractEEPROMGeneralCategory(self, device):
       
  1158         """
       
  1159         Extract "General" category data from slave ESI XML and generate EEPROM image data.
       
  1160         @param device : 'device' object in the slave ESI XML
       
  1161         @return eeprom : "Strings" category EEPROM image data
       
  1162         """ 
       
  1163         eeprom = []
       
  1164         data = ""
       
  1165         
       
  1166         # category header
       
  1167         eeprom.append("1e")
       
  1168         eeprom.append("00")
       
  1169         
       
  1170         # category length
       
  1171         eeprom.append("10")
       
  1172         eeprom.append("00")
       
  1173         
       
  1174         # word 1 : Group Type index and Image index in STRINGS Category
       
  1175         eeprom.append("{:0>2x}".format(self.GroupIdx))
       
  1176         eeprom.append("{:0>2x}".format(self.ImgIdx))
       
  1177         
       
  1178         # word 2 : Device Type index and Device Name index in STRINGS Category
       
  1179         eeprom.append("{:0>2x}".format(self.OrderIdx))
       
  1180         eeprom.append("{:0>2x}".format(self.NameIdx))
       
  1181         
       
  1182         # word 3 : Physical Layer Port info. and CoE Details
       
  1183         eeprom.append("01") # Physical Layer Port info - assume 01
       
  1184         #  CoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<CoE>
       
  1185         coe_details = 0
       
  1186         if device.getMailbox().getCoE() is not None:
       
  1187             coe_details = 1 # sdo enabled
       
  1188             for attr, bit in [(device.getMailbox().getCoE().getSdoInfo(), 1),
       
  1189                                (device.getMailbox().getCoE().getPdoAssign(), 2),
       
  1190                                (device.getMailbox().getCoE().getPdoConfig(), 3),
       
  1191                                (device.getMailbox().getCoE().getPdoUpload(), 4),
       
  1192                                (device.getMailbox().getCoE().getCompleteAccess(), 5)]:
       
  1193                 if attr==1 or attr==True:
       
  1194                     coe_details += 1<<bit        
       
  1195         eeprom.append("{:0>2x}".format(coe_details))
       
  1196         
       
  1197         # word 4 : FoE Details and EoE Details
       
  1198         #  FoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<FoE>
       
  1199         if device.getMailbox().getFoE() is not None:
       
  1200             eeprom.append("01")
       
  1201         else:
       
  1202             eeprom.append("00")
       
  1203         #  EoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<EoE>
       
  1204         if device.getMailbox().getEoE() is not None:
       
  1205             eeprom.append("01")
       
  1206         else:
       
  1207             eeprom.append("00")
       
  1208             
       
  1209         # word 5 : SoE Channels(reserved) and DS402 Channels
       
  1210         #  SoE Details; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<SoE>
       
  1211         if device.getMailbox().getSoE() is not None:
       
  1212             eeprom.append("01")
       
  1213         else:
       
  1214             eeprom.append("00")
       
  1215         #  DS402Channels; <EtherCATInfo>-<Descriptions>-<Devices>-<Device>-<Mailbox>-<CoE>: DS402Channels
       
  1216         if device.getMailbox().getCoE().getDS402Channels() == True \
       
  1217         or device.getMailbox().getCoE().getDS402Channels() == 1:
       
  1218             eeprom.append("01")
       
  1219         else:
       
  1220             eeprom.append("00")
       
  1221             
       
  1222         # word 6 : SysmanClass(reserved) and Flags
       
  1223         eeprom.append("00") # reserved
       
  1224         #  Flags 
       
  1225         en_safeop = False
       
  1226         en_lrw = False
       
  1227         if device.getType().getTcCfgModeSafeOp() == True \
       
  1228         or device.getType().getTcCfgModeSafeOp() == 1:
       
  1229             en_safeop = True
       
  1230         if device.getType().getUseLrdLwr() == True \
       
  1231         or device.getType().getUseLrdLwr() == 1:
       
  1232             en_lrw = True
       
  1233         
       
  1234         flags = "0b"+"000000"+str(int(en_lrw))+str(int(en_safeop))
       
  1235         eeprom.append("{:0>2x}".format(int(flags, 2)))
       
  1236             
       
  1237         # word 7 : Current On EBus (assume 0x0000)
       
  1238         eeprom.append("00")
       
  1239         eeprom.append("00")
       
  1240         # after word 7; couldn't analyze yet
       
  1241         eeprom.append("03")
       
  1242         eeprom.append("00")
       
  1243         eeprom.append("11")
       
  1244         eeprom.append("00")
       
  1245         eeprom.append("00")
       
  1246         eeprom.append("00")
       
  1247         eeprom.append("00")
       
  1248         eeprom.append("00")
       
  1249         eeprom.append("00")
       
  1250         eeprom.append("00")
       
  1251         eeprom.append("00")
       
  1252         eeprom.append("00")
       
  1253         eeprom.append("00")
       
  1254         eeprom.append("00")
       
  1255         eeprom.append("00")
       
  1256         eeprom.append("00")
       
  1257         eeprom.append("00")
       
  1258         eeprom.append("00")
       
  1259         
       
  1260         return eeprom
       
  1261     
       
  1262     def ExtractEEPROMFMMUCategory(self, device):
       
  1263         """
       
  1264         Extract "FMMU" category data from slave ESI XML and generate EEPROM image data.
       
  1265         @param device : 'device' object in the slave ESI XML
       
  1266         @return eeprom : "Strings" category EEPROM image data
       
  1267         """ 
       
  1268         eeprom = []
       
  1269         data = ""
       
  1270         count = 0 # number of FMMU
       
  1271         padflag = False
       
  1272         
       
  1273         for fmmu in device.getFmmu():
       
  1274             count += 1
       
  1275             if fmmu.getcontent() == "Outputs":
       
  1276                 data += "01"
       
  1277             if fmmu.getcontent() == "Inputs":
       
  1278                 data += "02"
       
  1279             if fmmu.getcontent() == "MBoxState":
       
  1280                 data += "03"
       
  1281         
       
  1282         # construct of EEPROM data
       
  1283         if data is not "":
       
  1284             #  category header
       
  1285             eeprom.append("28")
       
  1286             eeprom.append("00")
       
  1287             #  category length
       
  1288             if count%2 == 1:
       
  1289                 padflag = True
       
  1290                 eeprom.append("{:0>4x}".format((count+1)/2)[2:4])
       
  1291                 eeprom.append("{:0>4x}".format((count+1)/2)[0:2])
       
  1292             else: 
       
  1293                 eeprom.append("{:0>4x}".format((count)/2)[2:4])
       
  1294                 eeprom.append("{:0>4x}".format((count)/2)[0:2])
       
  1295             for i in range(count):
       
  1296                 if data == "":
       
  1297                     eeprom.append("00")
       
  1298                 else:
       
  1299                     eeprom.append(data[0:2])
       
  1300                 data = data[2:len(data)]
       
  1301             #  padding if length is odd bytes 
       
  1302             if padflag is True:
       
  1303                 eeprom.append("ff")       
       
  1304             
       
  1305         return eeprom
       
  1306     
       
  1307     def ExtractEEPROMSyncMCategory(self, device):
       
  1308         """
       
  1309         Extract "SyncM" category data from slave ESI XML and generate EEPROM image data.
       
  1310         @param device : 'device' object in the slave ESI XML
       
  1311         @return eeprom : "Strings" category EEPROM image data
       
  1312         """ 
       
  1313         eeprom = []
       
  1314         data = ""
       
  1315         number = {"MBoxOut":"01", "MBoxIn":"02", "Outputs":"03", "Inputs":"04"}
       
  1316         
       
  1317         for sm in device.getSm():
       
  1318             for attr in [sm.getStartAddress(),
       
  1319                          sm.getDefaultSize(),
       
  1320                          sm.getControlByte()]:
       
  1321                 if attr is not None:
       
  1322                     data += "{:0>4x}".format(ExtractHexDecValue(attr))[2:4]
       
  1323                     data += "{:0>4x}".format(ExtractHexDecValue(attr))[0:2]
       
  1324                 else:
       
  1325                     data += "0000"  
       
  1326             if sm.getEnable() == "1" or sm.getEnable() == True:
       
  1327                 data += "01"
       
  1328             else:
       
  1329                 data += "00"
       
  1330             data += number[sm.getcontent()]
       
  1331             
       
  1332         if data is not "":
       
  1333             #  category header
       
  1334             eeprom.append("29")
       
  1335             eeprom.append("00")
       
  1336             #  category length 
       
  1337             eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
       
  1338             eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
       
  1339             for i in range(len(data)/2):
       
  1340                 if data == "":
       
  1341                     eeprom.append("00")
       
  1342                 else:
       
  1343                     eeprom.append(data[0:2])
       
  1344                 data = data[2:len(data)]
       
  1345 
       
  1346         return eeprom
       
  1347     
       
  1348     def ExtractEEPROMPDOCategory(self, device, pdotype):
       
  1349         """
       
  1350         Extract ""PDO (Tx, Rx)"" category data from slave ESI XML and generate EEPROM image data.
       
  1351         @param device : 'device' object in the slave ESI XML
       
  1352         @param pdotype : identifier whether "TxPDO" or "RxPDO".
       
  1353         @return eeprom : "Strings" category EEPROM image data
       
  1354         """ 
       
  1355         eeprom = []
       
  1356         data = ""
       
  1357         count = 0
       
  1358         en_fixed = False
       
  1359         en_mandatory = False
       
  1360         en_virtual = False
       
  1361         
       
  1362         for element in eval("device.get%s()"%pdotype):
       
  1363             #  PDO Index
       
  1364             data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[2:4]
       
  1365             data += "{:0>4x}".format(ExtractHexDecValue(element.getIndex().getcontent()))[0:2]
       
  1366             #  Number of Entries
       
  1367             data += "{:0>2x}".format(len(element.getEntry()))
       
  1368             #  About Sync Manager
       
  1369             if element.getSm() is not None:
       
  1370                 data += "{:0>2x}".format(element.getSm())
       
  1371             else:
       
  1372                 data += "ff"
       
  1373             #  Reference to DC Synch (according to ET1100 documentation) - assume 0
       
  1374             data += "00"
       
  1375             #  Name Index
       
  1376             objname = ""
       
  1377             for name in element.getName():
       
  1378                 objname = name.getcontent()
       
  1379             for name in self.Strings:
       
  1380                 count += 1
       
  1381                 if objname == name:
       
  1382                     break
       
  1383             if len(self.Strings)+1 == count:
       
  1384                 data += "00"
       
  1385             else:
       
  1386                 data += "{:0>2x}".format(count)
       
  1387             count = 0
       
  1388             #  Flags; by Fixed, Mandatory, Virtual attributes ?
       
  1389             if element.getFixed() == True or 1:
       
  1390                 en_fixed = True
       
  1391             if element.getMandatory() == True or 1:
       
  1392                 en_mandatory = True
       
  1393             if element.getVirtual() == True or element.getVirtual():
       
  1394                 en_virtual = True
       
  1395             data += str(int(en_fixed)) + str(int(en_mandatory)) + str(int(en_virtual)) + "0"
       
  1396             
       
  1397             for entry in element.getEntry():
       
  1398                 #   Entry Index
       
  1399                 data += "{:0>4x}".format(ExtractHexDecValue(entry.getIndex().getcontent()))[2:4]
       
  1400                 data += "{:0>4x}".format(ExtractHexDecValue(entry.getIndex().getcontent()))[0:2]
       
  1401                 #   Subindex
       
  1402                 data += "{:0>2x}".format(int(entry.getSubIndex()))
       
  1403                 #   Entry Name Index
       
  1404                 objname = ""
       
  1405                 for name in entry.getName():
       
  1406                     objname = name.getcontent()
       
  1407                 for name in self.Strings:
       
  1408                     count += 1
       
  1409                     if objname == name:
       
  1410                         break
       
  1411                 if len(self.Strings)+1 == count:
       
  1412                     data += "00"
       
  1413                 else:
       
  1414                     data += "{:0>2x}".format(count)
       
  1415                 count = 0
       
  1416                 #   DataType
       
  1417                 if entry.getDataType() is not None:
       
  1418                     if entry.getDataType().getcontent() in self.BaseDataTypeDict:
       
  1419                         data += self.BaseDataTypeDict[entry.getDataType().getcontent()]
       
  1420                     else:
       
  1421                         data += "00"
       
  1422                 else:
       
  1423                     data += "00"
       
  1424                 #   BitLen
       
  1425                 if entry.getBitLen() is not None:
       
  1426                     data += "{:0>2x}".format(int(entry.getBitLen()))
       
  1427                 else:
       
  1428                     data += "00"
       
  1429                 #   Flags; by Fixed attributes ?
       
  1430                 en_fixed = False
       
  1431                 if entry.getFixed() == True or entry.getFixed() == 1:
       
  1432                     en_fixed = True
       
  1433                 data += str(int(en_fixed)) + "000"
       
  1434         
       
  1435         if data is not "":
       
  1436             #  category header
       
  1437             if pdotype == "TxPdo":
       
  1438                 eeprom.append("32")
       
  1439             elif pdotype == "RxPdo":
       
  1440                 eeprom.append("33")
       
  1441             else:
       
  1442                 eeprom.append("00")
       
  1443             eeprom.append("00")
       
  1444             #  category length 
       
  1445             eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
       
  1446             eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
       
  1447             data = str(data.lower())
       
  1448             for i in range(len(data)/2):
       
  1449                 if data == "":
       
  1450                     eeprom.append("00")
       
  1451                 else:
       
  1452                     eeprom.append(data[0:2])
       
  1453                 data = data[2:len(data)]
       
  1454         
       
  1455         return eeprom
       
  1456     
       
  1457     def ExtractEEPROMDCCategory(self, device):
       
  1458         """
       
  1459         Extract "DC(Distributed Clock)" category data from slave ESI XML and generate EEPROM image data.
       
  1460         @param device : 'device' object in the slave ESI XML
       
  1461         @return eeprom : "Strings" category EEPROM image data
       
  1462         """ 
       
  1463         eeprom = []
       
  1464         data = ""
       
  1465         count = 0
       
  1466         namecount = 0
       
  1467         
       
  1468         if device.getDc() is not None:
       
  1469             for element in device.getDc().getOpMode():
       
  1470                 count += 1
       
  1471                 #  assume that word 1-7 are 0x0000
       
  1472                 data += "0000"
       
  1473                 data += "0000"
       
  1474                 data += "0000"
       
  1475                 data += "0000"
       
  1476                 data += "0000"
       
  1477                 data += "0000"
       
  1478                 data += "0000"
       
  1479                 #  word 8-10
       
  1480                 #  AssignActivate
       
  1481                 if element.getAssignActivate() is not None:
       
  1482                     data += "{:0>4x}".format(ExtractHexDecValue(element.getAssignActivate()))[2:4]
       
  1483                     data += "{:0>4x}".format(ExtractHexDecValue(element.getAssignActivate()))[0:2]
       
  1484                 else:
       
  1485                     data += "0000"
       
  1486                 #  Factor of CycleTimeSync0 ? and default is 1?
       
  1487                 if element.getCycleTimeSync0() is not None:
       
  1488                     if element.getCycleTimeSync0().getFactor() is not None:
       
  1489                         data += "{:0>2x}".format(int(element.getCycleTimeSync0().getFactor()))
       
  1490                         data += "00"
       
  1491                     else:
       
  1492                         data += "0100"
       
  1493                 else:
       
  1494                     data += "0100"
       
  1495                 #  Index of Name in STRINGS Category
       
  1496                 #  Name Index
       
  1497                 objname = ""
       
  1498                 for name in element.getName():
       
  1499                     objname += name
       
  1500                 for name in self.Strings:
       
  1501                     namecount += 1
       
  1502                     if objname == name:
       
  1503                         break
       
  1504                 if len(self.Strings)+1 == namecount:
       
  1505                     data += "00"
       
  1506                 else:
       
  1507                     data += "{:0>2x}".format(namecount)
       
  1508                 namecount = 0
       
  1509                 data += "00"
       
  1510                 #  assume that word 11-12 are 0x0000
       
  1511                 data += "0000"
       
  1512                 data += "0000"
       
  1513                 
       
  1514         if data is not "":
       
  1515             #  category header
       
  1516             eeprom.append("3c")
       
  1517             eeprom.append("00")
       
  1518             #  category length 
       
  1519             eeprom.append("{:0>4x}".format(len(data)/4)[2:4])
       
  1520             eeprom.append("{:0>4x}".format(len(data)/4)[0:2])
       
  1521             data = str(data.lower())
       
  1522             for i in range(len(data)/2):
       
  1523                 if data == "":
       
  1524                     eeprom.append("00")
       
  1525                 else:
       
  1526                     eeprom.append(data[0:2])
       
  1527                 data = data[2:len(data)]
       
  1528     
       
  1529         return eeprom
       
  1530     
       
  1531     #-------------------------------------------------------------------------------
       
  1532     #                        Used Register Access
       
  1533     #-------------------------------------------------------------------------------
       
  1534     def RegRead(self, offset, length):
       
  1535         """
       
  1536         Read slave ESC register content using "ethercat reg_read -p %d %s %s" command.
       
  1537         Command example : "ethercat reg_read -p 0 0x0c00 0x0400"
       
  1538         @param offset : register address
       
  1539         @param length : register length
       
  1540         @return return_val : register data
       
  1541         """ 
       
  1542         error, return_val = self.Controler.RemoteExec(REG_READ%(self.Controler.GetSlavePos(), offset, length), return_val = None)
       
  1543         return return_val   
       
  1544     
       
  1545     def RegWrite(self, address, data):
       
  1546         """
       
  1547         Write data to slave ESC register using "ethercat reg_write -p %d %s %s" command.
       
  1548         Command example : "ethercat reg_write -p 0 0x0c04 0x0001"
       
  1549         @param address : register address
       
  1550         @param data : data to write
       
  1551         @return return_val : the execution result of "ethercat reg_write" (for error check)
       
  1552         """ 
       
  1553         error, return_val = self.Controler.RemoteExec(REG_WRITE%(self.Controler.GetSlavePos(), address, data), return_val = None)
       
  1554         return return_val 
       
  1555     
       
  1556     def Rescan(self):
       
  1557         """
       
  1558         Synchronize EEPROM data in master controller with the data in slave device after EEPROM write.
       
  1559         Command example : "ethercat rescan -p 0"
       
  1560         """ 
       
  1561         error, return_val = self.Controler.RemoteExec(RESCAN%(self.Controler.GetSlavePos()), return_val = None)
       
  1562     
       
  1563     #-------------------------------------------------------------------------------
       
  1564     #                        Common Use Methods
       
  1565     #-------------------------------------------------------------------------------
       
  1566     def CheckConnect(self, cyclic_flag):
       
  1567         """
       
  1568         Check connection status (1) between Beremiz and the master (2) between the master and the slave. 
       
  1569         @param cyclic_flag: 0 - one shot, 1 - periodic
       
  1570         @return True or False
       
  1571         """ 
       
  1572         if self.Controler.GetCTRoot()._connector is not None:
       
  1573             # Check connection between the master and the slave. 
       
  1574             # Command example : "ethercat xml -p 0"
       
  1575             error, return_val = self.Controler.RemoteExec(SLAVE_XML%(self.Controler.GetSlavePos()), return_val = None)
       
  1576             number_of_lines = return_val.split("\n")
       
  1577             if len(number_of_lines) <= 2 :  # No slave connected to the master controller
       
  1578                 if not cyclic_flag :
       
  1579                     self.CreateErrorDialog('No connected slaves')
       
  1580                 return False
       
  1581         
       
  1582             elif len(number_of_lines) > 2 :
       
  1583                 return True
       
  1584         else:                               
       
  1585             # The master controller is not connected to Beremiz host
       
  1586             if not cyclic_flag :
       
  1587                 self.CreateErrorDialog('PLC not connected!')
       
  1588             return False
       
  1589         
       
  1590     def CreateErrorDialog(self, mention):
       
  1591         """
       
  1592         Create a dialog to indicate error or warning.
       
  1593         @param mention : Error String
       
  1594         """ 
       
  1595         app_frame = self.Controler.GetCTRoot().AppFrame
       
  1596         dlg = wx.MessageDialog (app_frame, mention, 
       
  1597                                 ' Warning...', 
       
  1598                                 wx.OK | wx.ICON_INFORMATION)
       
  1599         dlg.ShowModal()
       
  1600         dlg.Destroy()