etherlab/EthercatCFileGenerator.py
changeset 2643 b98d9e08231f
parent 2437 105c20fdeb19
parent 2641 c9deff128c37
--- a/etherlab/EthercatCFileGenerator.py	Wed Nov 13 11:21:04 2019 +0100
+++ b/etherlab/EthercatCFileGenerator.py	Mon Nov 25 08:10:45 2019 +0100
@@ -70,6 +70,37 @@
     }
 """
 
+SLAVE_OUTPUT_PDO_DEFAULT_VALUE_BIT = """
+    {
+        uint8_t value[%(data_size)d];
+        if (ecrt_master_sdo_upload(master, %(slave)d, 0x%(index).4x, 0x%(subindex).2x, (uint8_t *)value, %(data_size)d, &result_size, &abort_code)) {
+            SLOGF(LOG_CRITICAL, "EtherCAT failed to get default value for output PDO in slave %(device_type)s at alias %(alias)d and position %(position)d. Error: %%ud", abort_code);
+            goto ecat_failed;
+        }
+        %(real_var)s = EC_READ_%(data_type)s((uint8_t *)value, %(subindex)d);
+    }
+"""
+
+
+SLAVE_INPUT_PDO_DEFAULT_VALUE = """
+    {
+        uint8_t value[%(data_size)d];
+        if (ecrt_master_sdo_upload(master, %(slave)d, 0x%(index).4x, 0x%(subindex).2x, (uint8_t *)value, %(data_size)d, &result_size, &abort_code)) {
+            SLOGF(LOG_CRITICAL, "EtherCAT failed to get default value for input PDO in slave %(device_type)s at alias %(alias)d and position %(position)d. Error: %%ud", abort_code);
+            goto ecat_failed;
+        }
+        %(real_var)s = EC_READ_%(data_type)s((uint8_t *)value);
+    }
+"""
+
+DC_VARIABLE ="""
+#define DC_ENABLE       %(dc_flag)d
+"""
+
+CONFIG_DC = """
+    ecrt_slave_config_dc (slave%(slave)d, 0x0%(assign_activate)ld, %(sync0_cycle_time)d, %(sync0_shift_time)d, %(sync1_cycle_time)d, %(sync1_shift_time)d);
+"""
+
 
 def ConfigureVariable(entry_infos, str_completion):
     entry_infos["data_type"] = DATATYPECONVERSION.get(entry_infos["var_type"], None)
@@ -192,10 +223,15 @@
             "pdos_configuration_declaration": "",
             "slaves_declaration": "",
             "slaves_configuration": "",
+            # add jblee
+            "slaves_input_pdos_default_values_extraction": "",
             "slaves_output_pdos_default_values_extraction": "",
             "slaves_initialization": "",
             "retrieve_variables": [],
             "publish_variables": [],
+            #-----------This Code templete for dc -------------------#
+            "dc_variable" : "",
+            "config_dc": ""
         }
 
         # Initialize variable storing variable mapping state
@@ -208,6 +244,9 @@
         # Initialize dictionary storing alias auto-increment position values
         alias = {}
 
+        # add jblee
+        slotNumber = 1
+        
         # Generating code for each slave
         for (slave_idx, slave_alias, slave) in self.Slaves:
             type_infos = slave.getType()
@@ -244,11 +283,14 @@
                 # If device support CanOpen over Ethernet, adding code for calling
                 # init commands when initializing slave in master code template strings
                 initCmds = []
+                
                 for initCmd in device_coe.getInitCmd():
                     initCmds.append({
                         "Index": ExtractHexDecValue(initCmd.getIndex()),
                         "Subindex": ExtractHexDecValue(initCmd.getSubIndex()),
-                        "Value": initCmd.getData().getcontent()})
+                        #"Value": initCmd.getData().getcontent()})
+                        "Value": int(initCmd.getData().text, 16)})
+                
                 initCmds.extend(slave.getStartupCommands())
                 for initCmd in initCmds:
                     index = initCmd["Index"]
@@ -314,12 +356,106 @@
                 pdos_index = []
                 exclusive_pdos = {}
                 selected_pdos = []
-                for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
-                                      [(pdo, "Outputs") for pdo in device.getRxPdo()]):
-
+
+                # add jblee
+                TxPdoData = []
+                RxPdoData = []
+                PdoData = []
+
+                # add jblee
+                if len(device.getTxPdo() + device.getRxPdo()) > 0:
+                    for pdo in device.getTxPdo():
+                        PdoData.append((pdo, "Inputs"))
+                    for pdo in device.getRxPdo():
+                        PdoData.append((pdo, "Outputs"))               
+
+                # mod jblee
+                #for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
+                #                      [(pdo, "Outputs") for pdo in device.getRxPdo()]):
+                #for pdo, pdo_type in (TxPdoData + RxPdoData):
+                data_files = os.listdir(self.Controler.CTNPath())
+                PDODataList = []
+                MDPData = []
+                RxPDOData = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getRxPDO()
+                TxPDOData = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getTxPDO()
+                PDOList = RxPDOData.split() + TxPDOData.split()
+                for PDOIndex in PDOList:
+                    if PDOIndex in ["RxPDO", "TxPDO", "None"]:
+                        continue
+                    PDODataList.append(int(PDOIndex, 0))
+
+                # add jblee for DC Configuration
+                dc_enable = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Enable()
+                sync0_cycle_time = 0
+                sync0_shift_time = 0
+                sync1_cycle_time = 0
+                sync1_shift_time = 0
+                if dc_enable :
+                    sync0_cycle_token = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Sync0_Cycle_Time()
+                    if sync0_cycle_token != "None":
+                        sync0_cycle_time = int(sync0_cycle_token.split("_")[1]) * 1000
+                    sync0_shift_token = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Sync0_Shift_Time()
+                    if sync0_shift_token != "None":
+                        sync0_shift_time = int(sync0_shift_token) * 1000
+                    sync1_cycle_token = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Sync1_Cycle_Time()
+                    if sync1_cycle_token != "None":
+                        sync1_cycle_time = int(sync1_cycle_token.split("_")[1]) * 1000
+                    sync1_shift_token = self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Sync1_Shift_Time()
+                    if sync1_shift_token != "None":
+                        sync1_shift_time = int(sync1_shift_token) * 1000
+                    
+                    dc_config_data = {
+                        "slave" : slave_idx,
+                        "assign_activate" : int(self.Controler.GetChildByIECLocation((slave_idx,)).BaseParams.getDC_Assign_Activate()),
+                        "sync0_cycle_time" : sync0_cycle_time,
+                        "sync0_shift_time" : sync0_shift_time,
+                        "sync1_cycle_time" : sync1_cycle_time,
+                        "sync1_shift_time" : sync1_shift_time,
+                    }
+
+                    if dc_enable and not str_completion["dc_variable"] :
+                        str_completion["dc_variable"] += DC_VARIABLE % {"dc_flag" : dc_enable}
+                    str_completion["config_dc"] += CONFIG_DC % dc_config_data
+
+                for data_file in data_files:
+                    slave_path = os.path.join(self.Controler.CTNPath(), data_file)
+                    if os.path.isdir(slave_path):
+                        CheckConfNodePath = os.path.join(slave_path, "baseconfnode.xml")
+                        confNodeFile = open(CheckConfNodePath, 'r')
+                        checklines = confNodeFile.readlines()
+                        confNodeFile.close()
+                        # checklines(ex) : <BaseParams xmlns:xsd="http://www.w3.org/2001/XMLSchema" IEC_Channel="0" Name="EthercatSlave_0"/>
+                        # checklines[1].split() : [<BaseParams, xmlns:xsd="http://www.w3.org/2001/XMLSchema",
+                        #                           IEC_Channel="0", Name="EthercatSlave_0"/>]
+                        # checklines[1].split()[2] : IEC_Channel="0"
+                        # checklines[1].split()[2].split("\"") = [IEC_Channel=, 0, ]
+                        pos_check = int(checklines[1].split()[2].split("\"")[1])
+                        if slave_idx == pos_check:
+                            MDPDataFilePath = os.path.join(slave_path, "DataForMDP.txt")
+                            if os.path.isfile(MDPDataFilePath):
+                                MDPDataFile = open(MDPDataFilePath, 'r')
+                                MDPData = MDPDataFile.readlines()
+                                MDPDataFile.close()
+
+                        for MDPLine in MDPData:
+                            if MDPLine == "\n":
+                                continue
+                            module_pos = int(MDPLine.split()[-1])
+                            module = self.Controler.CTNParent.GetSelectModule(module_pos)
+                            for pdo in module.getTxPdo():
+                                PdoData.append((pdo, "Inputs"))
+                                PDODataList.append(ExtractHexDecValue(pdo.getIndex().getcontent()))
+                            for pdo in module.getRxPdo():
+                                PdoData.append((pdo, "Outputs"))
+                                PDODataList.append(ExtractHexDecValue(pdo.getIndex().getcontent()))
+
+                for pdo, pdo_type in PdoData:
                     pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
                     pdos_index.append(pdo_index)
 
+                    if PDODataList and (pdo_index in PDODataList):
+                        continue
+
                     excluded_list = pdo.getExclude()
                     if len(excluded_list) > 0:
                         exclusion_list = [pdo_index]
@@ -330,12 +466,14 @@
                         exclusion_scope = exclusive_pdos.setdefault(tuple(exclusion_list), [])
 
                         entries = pdo.getEntry()
+
                         pdo_mapping_match = {
                             "index": pdo_index,
                             "matching": 0,
                             "count": len(entries),
                             "assigned": pdo.getSm() is not None
                         }
+
                         exclusion_scope.append(pdo_mapping_match)
 
                         for entry in entries:
@@ -364,30 +502,57 @@
                         for pdo in exclusion_scope[start_excluding_index:]
                         if PdoAssign or not pdo["assigned"]])
 
-                for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
-                                      [(pdo, "Outputs") for pdo in device.getRxPdo()]):
-                    entries = pdo.getEntry()
-
+                # mod jblee
+                #for pdo, pdo_type in ([(pdo, "Inputs") for pdo in device.getTxPdo()] +
+                #                      [(pdo, "Outputs") for pdo in device.getRxPdo()]):
+                #for pdo, pdo_type in (TxPdoData + RxPdoData):
+                entry_check_list = []
+                index_padding = 1
+                for pdo, pdo_type in PdoData:
+                    entries = pdo.getEntry()                   
+                    
                     pdo_index = ExtractHexDecValue(pdo.getIndex().getcontent())
                     if pdo_index in excluded_pdos:
                         continue
-
-                    pdo_needed = pdo_index in selected_pdos
-
-                    entries_infos = []
-
+                    if PDODataList and (pdo_index not in PDODataList):
+                        continue
+                    
+                    #pdo_needed = pdo_index in selected_pdos
+                    pdo_needed = pdo_index in PDODataList
+
+                    if len(MDPData) > 0:
+                        pdo_index += index_padding
+                        index_padding += 1
+
+                    entries_infos = []                   
                     for entry in entries:
                         index = ExtractHexDecValue(entry.getIndex().getcontent())
                         subindex = ExtractHexDecValue(entry.getSubIndex())
+
+                        # add jblee
+                        if len(MDPData) > 0:
+                            increse = self.Controler.CTNParent.GetMDPInfos(type_infos)                          
+                            if increse and index != 0:
+                                index += int(increse[0][2]) * slotNumber
+                                
                         entry_infos = {
                             "index": index,
                             "subindex": subindex,
                             "name": ExtractName(entry.getName()),
                             "bitlen": entry.getBitLen(),
                         }
+
+                        entry_infos.update(type_infos)
+                        #temp_data = "    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos
+                        check_data = "{0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}" % entry_infos
+                        if entry_check_list and check_data in entry_check_list:
+                            if (entry_infos["index"] == 0) or (entry_infos["name"] == None):
+                                pass
+                            else: 
                         entry_infos.update(type_infos)
                         entries_infos.append("    {0x%(index).4x, 0x%(subindex).2x, %(bitlen)d}, /* %(name)s */" % entry_infos)
-
+                        entry_check_list.append(check_data)
+                        
                         entry_declaration = slave_variables.get((index, subindex), None)
                         if entry_declaration is not None and not entry_declaration["mapped"]:
                             pdo_needed = True
@@ -421,9 +586,26 @@
 
                             ConfigureVariable(entry_infos, str_completion)
 
-                            str_completion["slaves_output_pdos_default_values_extraction"] += \
-                                SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos
-
+                            if entry_infos["data_type"] == "BIT" :
+                                str_completion["slaves_output_pdos_default_values_extraction"] += \
+                                    SLAVE_OUTPUT_PDO_DEFAULT_VALUE_BIT % entry_infos
+                            else :
+                                str_completion["slaves_output_pdos_default_values_extraction"] += \
+                                    SLAVE_OUTPUT_PDO_DEFAULT_VALUE % entry_infos
+
+                        elif pdo_type == "Inputs" and entry.getDataType() is not None and device_coe is not None:
+                            data_type = entry.getDataType().getcontent()
+                            entry_infos["dir"] = "I"
+                            entry_infos["data_size"] = max(1, entry_infos["bitlen"] / 8)
+                            entry_infos["data_type"] = DATATYPECONVERSION.get(data_type)
+                            entry_infos["var_type"] = data_type
+                            entry_infos["real_var"] = "slave%(slave)d_%(index).4x_%(subindex).2x_default" % entry_infos
+                            
+                            ConfigureVariable(entry_infos, str_completion)
+                            
+                            str_completion["slaves_input_pdos_default_values_extraction"] += \
+                                SLAVE_INPUT_PDO_DEFAULT_VALUE % entry_infos
+                    
                     if pdo_needed:
                         for excluded in pdo.getExclude():
                             excluded_index = ExtractHexDecValue(excluded.getcontent())
@@ -448,6 +630,9 @@
                              "entries_number": len(entries_infos),
                              "fixed": pdo.getFixed() is True})
 
+                    # for MDP
+                    slotNumber += 1
+            
                 if PdoConfig and PdoAssign:
                     dynamic_pdos = {}
                     dynamic_pdos_number = 0
@@ -541,8 +726,8 @@
 
                 pdo_offset = 0
                 entry_offset = 0
+                slotNumber = 1
                 for sync_manager_infos in sync_managers:
-
                     for pdo_infos in sync_manager_infos["pdos"]:
                         pdo_infos["offset"] = entry_offset
                         pdo_entries = pdo_infos["entries"]
@@ -564,17 +749,17 @@
                     pdos_infos[element] = "\n".join(pdos_infos[element])
 
                 str_completion["pdos_configuration_declaration"] += SLAVE_PDOS_CONFIGURATION_DECLARATION % pdos_infos
-
-            for (index, subindex), entry_declaration in slave_variables.iteritems():
-                if not entry_declaration["mapped"]:
-                    message = _("Entry index 0x{a1:.4x}, subindex 0x{a2:.2x} not mapped for device {a3}").\
-                              format(a1=index, a2=subindex, a3=type_infos["device_type"])
-                    self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
-
-        for element in ["used_pdo_entry_offset_variables_declaration",
-                        "used_pdo_entry_configuration",
-                        "located_variables_declaration",
-                        "retrieve_variables",
+            
+            #for (index, subindex), entry_declaration in slave_variables.iteritems():
+            #    if not entry_declaration["mapped"]:
+            #        message = _("Entry index 0x%4.4x, subindex 0x%2.2x not mapped for device %s") % \
+            #                        (index, subindex, type_infos["device_type"])
+            #        self.Controler.GetCTRoot().logger.write_warning(_("Warning: ") + message + "\n")
+                    
+        for element in ["used_pdo_entry_offset_variables_declaration", 
+                        "used_pdo_entry_configuration", 
+                        "located_variables_declaration", 
+                        "retrieve_variables", 
                         "publish_variables"]:
             str_completion[element] = "\n".join(str_completion[element])