function DGMGen
%%该函数用于VCU平台化应用层软件(模型)诊断模块的自动化生成
%%同时可通过配置选择是否生成 obd_config.h obd_vars_auto.c obd_vars_auto.h 三个DTC存储配置的代码文件

% Construct a questdlg with three options
ModelGen=false;
CodeGen = false;
choice = questdlg('VCU诊断生成工具内容选择', ...
	'Choice Menu', ...
	'应用层模型','接口代码','模型和代码','应用层模型');
% Handle response
switch choice
    case '应用层模型'
        ModelGen = true;
    case '接口代码'
        CodeGen = true;
    case '模型和代码'
        ModelGen = true;
        CodeGen = true;
end


%% %%%%%%%%%%%%%%%%%%%%%%%%%%%% Pre Process %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 导入数据
[name,~]=uigetfile('*.xlsx','导入诊断列表数据');
[~,~,data_raw]=xlsread(name,'整车控制器故障诊断策略设计');
%% 数据处理
[feature_cell,fault_cell,param_cell]=fault_format(data_raw);
[feature_cell_group,fault_cell_group,param_cell_group]=fault_format_group(data_raw);
feature_num=length(feature_cell);
feature_num_group=length(feature_cell_group);
% branch_str=evalin('base','branch');

%% 模型生成
if ModelGen
waitbar_rate=0.1;
waitbar_handle=waitbar(waitbar_rate,'导入诊断列表数据...');
frames=java.awt.Frame.getFrames();
frames(end).setAlwaysOnTop(1);
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DD %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DD_excel_name='DD_DGM_cal.xlsx';
% title={'name','value','min','max','datatype','uint','description'};
% Cal_Content(1,:)=title;
% Sig_Content(1,:)=title;
% Const_Content(1,:)=title;
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DD Gen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DD_excel_name='DD_DGM.xlsx';

DD_Signal_line=1;
DD_Calibrations_line=1;
DD_Constants_line=1;
Inputs_line=1;
Outputs_line=1;
DD_ISP_line=1;

excel_title={'name'	
             'value'
             'min'	 
             'max'
             'data_type'
             'uints'
             'description'
             };
Signal_content(DD_Signal_line,:)=excel_title;
DD_Signal_line=DD_Signal_line+1;

Calibration_content(DD_Calibrations_line,:)=excel_title;
DD_Calibrations_line=DD_Calibrations_line+1;

Constant_content(DD_Constants_line,:)=excel_title;
DD_Constants_line=DD_Constants_line+1;

Inputs_content(Inputs_line,:)=excel_title;
Inputs_line=Inputs_line+1;

Outputs_content(Outputs_line,:)=excel_title;
Outputs_line=Outputs_line+1;

ISP_content(DD_ISP_line,:)=excel_title;
DD_ISP_line=DD_ISP_line+1;

% Constant 固定的数据对象,包括输出信号,reaction 数量,reaction序号等
Constant_content(DD_Constants_line,:)={'CeDGM_PTFIDNum';
                                        '28';
                                        '1';
                                        '32';
                                        'uint8'; 
                                        'NA';                  
                                        'PT故障处理数量';                   
                                         };
                 DD_Constants_line=DD_Constants_line+1;
Constant_content(DD_Constants_line,:)={'CeDGM_AUXFIDNum';
                                        '21';
                                        '1';
                                        '32';
                                        'uint8'; 
                                        'NA';                  
                                        'AUX故障处理数量';                   
                                         };
                  DD_Constants_line=DD_Constants_line+1;
                                     
reaction_list= {'DRVDSBL','1','1','32','uint8','NA','驱动禁止';...    % PT起始
                'RGNDSBL','2','1','32','uint8','NA','回馈禁止';...
                'PWRLIM1','3','1','32','uint8','NA','限功率1(-30kw/50kw)';...
                'PWRLIM2','4','1','32','uint8','NA','限功率2(-10kw/20kw)';...
                'PWRLIM3','5','1','32','uint8','NA','限功率3(-5kw/10kw)';...
                'LMPHOME','6','1','32','uint8','NA','跛行';...
                'VSPLIM1','7','1','32','uint8','NA','车速限制1(60km/h)';...
                'VSPLIM2','8','1','32','uint8','NA','车速限制2(20km/h)';...
                'MOTDIBL1','9','1','32','uint8','NA','禁止电机1';...
                'MOTDIBL2','10','1','32','uint8','NA','禁止电机2';...
                'MOTDIBL3','11','1','32','uint8','NA','禁止电机3';...
                'MOTDIBL4','12','1','32','uint8','NA','禁止电机4';...
                'EMGHVOFF','13','1','32','uint8','NA','紧急高压下电';...
                'QUKHVOFF','14','1','32','uint8','NA','快速高压下电';...
                'NORMHVOFF','15','1','32','uint8','NA','高压下电';...
                'HVOFFVEHSTOP','16','1','32','uint8','NA','停车高压下电';...
                'CHGHVOFF','17','1','32','uint8','NA','充电高压下电';...
                'HVONBREK','18','1','32','uint8','NA','高压上电退出';...
                'HVONFOBD','19','1','32','uint8','NA','禁止高压上电(非充电)';...
                'CHGHVONFOBD','20','1','32','uint8','NA','禁止高压上电(充电)';...
                'BATDSBLDA','21','1','32','uint8','NA','禁止A包放电';...
                'BATDSBLDB','22','1','32','uint8','NA','禁止B包放电';...
                'BATDSBLDC','23','1','32','uint8','NA','禁止C包放电';...
                'BATDSBLCA','24','1','32','uint8','NA','禁止A包充电';...
                'BATDSBLCB','25','1','32','uint8','NA','禁止B包充电';...
                'BATDSBLCC','26','1','32','uint8','NA','禁止C包充电';...
                'COMBDSBL','27','1','32','uint8','NA','禁止内燃机增程器';...
                'HYDDSBL','28','1','32','uint8','NA','禁止氢增程器';...
                'READYDSBL','29','1','32','uint8','NA','禁止Ready';...
                'DCCFULPWR','33','1','32','uint8','NA','DCDC最大功率运行';... % AUX起始
                'DCCDSBL','34','1','32','uint8','NA','禁止DCDC';...
                'ACDSBL','35','1','32','uint8','NA','禁止空调';...
                'PMPFULPWR','36','1','32','uint8','NA','水泵最大功率运行';...
                'FANFULPWR','37','1','32','uint8','NA','风扇最大功率运行';...
                'PMPDSBL','38','1','32','uint8','NA','禁止水泵';...
                'FANDSBL','39','1','32','uint8','NA','禁止风扇';...
                'PRETHERMFOBD','40','1','32','uint8','NA','预加热禁止';...
                'PTCDSBL','41','1','32','uint8','NA','PTC禁止';...
                'QUKCHGFOBD','42','1','32','uint8','NA','快充禁止';...
                'SLOCHGFOBD','43','1','32','uint8','NA','慢充禁止';...
                'FORCENP','44','1','32','uint8','NA','强制N/P挡';...
                'SHFTFOBD','45','1','32','uint8','NA','禁止换挡';...
                'PWRLIMWRN','46','1','32','uint8','NA','限功率故障灯';...
                'SYSFLTWRN','47','1','32','uint8','NA','整车系统故障灯';...
                'DNGWRN','48','1','32','uint8','NA','危险报警提示';...
                'MNTNWRN','49','1','32','uint8','NA','维修提示';...
                'ESPFOBD','50','1','32','uint8','NA','禁止ESP扭矩介入';...
                'ACCFOBD','51','1','32','uint8','NA','禁止ACC扭矩介入';...
                'APAFOBD','52','1','32','uint8','NA','禁止APA扭矩介入';...
                'REGFOBD','53','1','32','uint8','NA','禁止REG扭矩介入'};
[list_num,~]=size(reaction_list);
for i=1:list_num
    Constant_content(DD_Constants_line,:)={ reaction_list{i,1};
                                            reaction_list{i,2};
                                            reaction_list{i,3};
                                            reaction_list{i,4};
                                            reaction_list{i,5};
                                            reaction_list{i,6};                  
                                            reaction_list{i,7};                 
                                            };
    DD_Constants_line=DD_Constants_line+1;
end

% Signal固定的数据对象
Signal_content(DD_Signal_line,:)={'VeDGM_flgFltReactnPt';
                                        '0';
                                        '0';
                                        '4294967295';
                                        'uint32'; 
                                        'NA';                  
                                        '系统故障处理PT';                   
                                         };
 DD_Signal_line=DD_Signal_line+1;
 Signal_content(DD_Signal_line,:)={'VeDGM_flgFltReactnAux';
                                        '0';
                                        '0';
                                        '4294967295';
                                        'uint32'; 
                                        'NA';                  
                                        '系统故障处理AUX';                   
                                         };
 DD_Signal_line=DD_Signal_line+1;
Signal_content(DD_Signal_line,:)={'VeDGM_flgFltReactn';
                                        '0';
                                        '0';
                                        '4294967295';
                                        'uint32'; 
                                        'NA';                  
                                        '系统故障处理(数组)';                   
                                         };
 DD_Signal_line=DD_Signal_line+1;
 Signal_content(DD_Signal_line,:)={'VeDGM_enmVehFltLvl';
                                        '0';
                                        '0';
                                        '4';
                                        'uint8'; 
                                        'NA';                  
                                        '故障等级';                   
                                         };
 DD_Signal_line=DD_Signal_line+1;

% NRC输出
Outputs_content(Outputs_line,:)={'app_flg_udsEcuRstAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '11服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;
Outputs_content(Outputs_line,:)={'app_flg_udsCommCtrlAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '28服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;
Outputs_content(Outputs_line,:)={'app_flg_udsDTCSettingAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '85服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;
Outputs_content(Outputs_line,:)={'app_flg_udsReadDataAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '22服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;
Outputs_content(Outputs_line,:)={'app_flg_udsWriteDataAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '2E服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;
Outputs_content(Outputs_line,:)={'app_flg_udsClearDTCAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '14服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;
Outputs_content(Outputs_line,:)={'app_flg_udsRoutineCtrlAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '31服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;
Outputs_content(Outputs_line,:)={'app_flg_udsIOCtrlAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '2F服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;
Outputs_content(Outputs_line,:)={'app_flg_udsSessionSetAllowed';
                                  '0';
                                  '0';
                                  '255';
                                  'uint8'; 
                                  'NA';                  
                                  '10服务NRC';                   
                                   };
                Outputs_line=Outputs_line+1;

%% reaction 标定量
%目前是放在constant sheet里
for i=1:feature_num
    if ~isempty(fault_cell{i})
      [~,DTC_num]=size(fault_cell{i});
      for j=1:DTC_num
        Constant_content(DD_Constants_line,:)={param_cell{i}{j,7};... %name
                             num2str(param_cell{i}{j,8});...        %value
                             num2str(0);                            %min
                             num2str(4294967295);                   %max
                             'uint32';                              %datatype
                             'NA';                                  %uint
                             '故障响应标定量(PT)';                   %description
                             };
        Constant_content(DD_Constants_line+1,:)={param_cell{i}{j,9};... %name
                             num2str(param_cell{i}{j,10});...       %value
                             num2str(0);                            %min
                             num2str(4294967295);                   %max
                             'uint32';                              %datatype
                             'NA';                                  %uint
                             '故障响应标定量(AUX)';                  %description
                             };
        DD_Constants_line=DD_Constants_line+2;
      end
    end
end
        

%% 模型文件创建
model_name=['DGM'];
newbd=new_system(model_name);
save_system(newbd,[pwd,'\',model_name]);
load_system(model_name);

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 注释 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
note = Simulink.Annotation([model_name,'/模块说明:',newline...
                                'DGM库模型由故障诊断列表自动生成,该库模型包含',newline...
                                'DFC_Feature,FID和DGM三部分',newline...
                                '',newline...
                                'DFC_Feature: 故障汇总模块',newline...
                                '用户将对应的模块放置到各功能模块模型中使用,',newline...
                                '该模块的作用是将各功能模块的故障信号生成一个一维数组(DFC),每个数组成员为',newline...
                                'uint32的变量,每一位对应一个故障,该数组信号会传递到DGM模块进行故障处理',newline...
                                '',newline...
                                'DGM:故障处理模块',newline...
                                '该模块将各功能模块DFC信号中的故障信号提取出来,并进行故障条件 ,故障确诊,',newline...
                                '故障响应等处理,输出故障响应信号至各功能模块',newline...
                                '',newline...
                                'FID',newline...
                                '该模块用于提取DGM输出的故障响应信号中的故障处理信号,通过双击模块并打开',newline...
                                '下拉菜单,选择需要的故障处理信号.']);
note.position = [-500,-300];
note.FontSize = 16;
note.BackgroundColor = 'lightBlue';

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FID %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FID_Lib=add_block('AI_common_lib/Fault Operation/FID',[model_name,'/','FID']);
% set_param(FID_Lib,'Position',[-500   640   -430   680]);



%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DFC Pack %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
waitbar(0.2,waitbar_handle,'DFC_Pack模块生成中...');  

for feature_cnt=1:feature_num
    feature_name=feature_cell{feature_cnt};
    DFC_Pack_ss=add_block('simulink/Commonly Used Blocks/Subsystem',[model_name,'/',feature_name,'_DFC_Pack']);
    Simulink.SubSystem.deleteContents(DFC_Pack_ss);
    
    clear fault_in_cell;
    fault_in_cell=fault_cell{feature_cnt}(1,:);
    %如果 输入故障信号名为空,说明该故障对应两个DTC,需要使用前一行的故障名
    
    fault_num=length(fault_in_cell);
    set_param(DFC_Pack_ss,'Position',[(feature_cnt-1)*250   0   (feature_cnt-1)*250+200   20*(fault_num+1)]);
    roll_cnt=-31;
    roll_num=1;
    Bus_blk=add_block('simulink/Commonly Used Blocks/Bus Creator',[model_name,'/',feature_name,'_DFC_Pack/Bus']);
    Out_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/',feature_name,'_DFC_Pack/',feature_name,'_DFC']);
    
    n_add=1;
    for fault_cnt=1:fault_num
        %num_suffix用于每组DFC输出信号及Ovrd标定量的命名
        num_suffix=num2str(roll_num-1);
        if num_suffix=='0'
            num_suffix='';
        end
           
       fault_name=fault_in_cell{fault_cnt};
       
    %多个故障有可能来自同一个故障源,使用try生成Inport,如果同一个故障源,则只可能生成一个Inport   
    try
       Inport_blk=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/',feature_name,'_DFC_Pack/',fault_name]);
                  set_param(Inport_blk,'Position',[0    (fault_cnt-1)*20    30    (fault_cnt-1)*20+14],'ShowName','on');
                  
       Inport_blk_add=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/',fault_name]);
                  set_param(Inport_blk_add,'Position',[-250    (n_add)*40+30    -220   (n_add)*40+30+14],'ShowName','on');
       Inport_line_add=add_line([model_name],[fault_name,'/1'],[feature_name,'_DFC_Pack/',num2str(n_add)],'autorouting','smart');          
                  set_param(Inport_line_add,'Name',fault_name);
       Inport_handle=get_param(Inport_line_add,'SrcPortHandle');
                  set_param(Inport_handle,'MustResolveToSignalObject','on');
                  
       ISP_content(DD_ISP_line,:)={fault_name%'var_name'	           %%%新增ISP DD%%%
                                    '0'%'initial_value'
                                    '0'%'min_value'	
                                    '1'%'max_value'
                                    'boolean'%'data_type'
                                    'NA'%'uints'
                                    'NA'%'description'
                                   };
                                   DD_ISP_line=DD_ISP_line+1;
       n_add=n_add+1;
                  
                  
       
    catch
%         Inport_blk=add_block([model_name,'/',feature_name,'_DFC_Pack/',fault_name],[model_name,'/',feature_name,'_DFC_Pack/',fault_name,num2str(duplicate_cnt)],'CopyOption','duplicate');
%                 set_param(Inport_blk,'Position',[0    (fault_cnt-1)*20    30    (fault_cnt-1)*20+14],'ShowName','on');
%         duplicate_cnt=duplicate_cnt+1;
    end
         
        
        % 当roll_cnt=-31时,说明是每一组(32个故障的第1个故障),需要生成一个子系统
        if roll_cnt==-31
            %剩余故障数计算
            remain_num=fault_num-32*(roll_num-1);
            % 如果剩余故障数大于32,current_group_num=32
            % 如果剩余故障树小于32,current_group_num=remain_num
            if remain_num>32
                current_group_num=32;
            else
                current_group_num=remain_num;
            end
            
            %生成DFC_unitXX子系统及内部模块
            DFC_blk=add_block('simulink/Commonly Used Blocks/Subsystem',[model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num)]);
                    Simulink.SubSystem.deleteContents(DFC_blk);
                    
            for flt_cnt=1:current_group_num
                %生成Constant0
                if flt_cnt==1
                   Constant_blk=add_block('simulink/Commonly Used Blocks/Constant',[model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num),'/BitSet',num2str(0)]);
                                set_param(Constant_blk,'Position',[-65   -40   -35   -10],'OutDataTypeStr','uint32','Value','0','ShowName','off');
                end
                Inport_blk=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num),'/Flt',num2str(flt_cnt)]);
                           set_param(Inport_blk,'Position',[-120 8+30*(flt_cnt-1) -90 22+30*(flt_cnt-1)],'ShowName','off');
                BitSet_blk=add_block('AI_common_lib/Logic and Bit Operations/SwitchBitSet',[model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num),'/BitSet',num2str(flt_cnt)]);
                           set_param(BitSet_blk,'Position',[0 30*(flt_cnt-1) 60 20+30*(flt_cnt-1)],'MaskValueString',num2str(32-flt_cnt),'ShowName','off');
                add_line([model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num)],['BitSet',num2str(flt_cnt-1),'/1'],['BitSet',num2str(flt_cnt),'/1']);
                add_line([model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num)],['Flt',num2str(flt_cnt),'/1'],['BitSet',num2str(flt_cnt),'/2']);
                
                %生成Outport及连线
                if flt_cnt==current_group_num
                    Output_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num),'/Out']);
                               set_param(Output_blk,'Position',[220 33+30*(flt_cnt-1) 250 47+30*(flt_cnt-1)],'ShowName','off');
                    
                    Ovrdval_name=['KeDGM_b',feature_name,'DFC',num2str(num_suffix),'Ovrdval'];
                    Cal_Const_blk=add_block('simulink/Commonly Used Blocks/Constant',[model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num),'/Cal']);
                              set_param(Cal_Const_blk,'Position',[-120   35+30*(flt_cnt-1)   60   65+30*(flt_cnt-1)],'Value',Ovrdval_name,'ShowName','off');
                    Bitwise_blk=add_block('simulink/Logic and Bit Operations/Bitwise Operator',[model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num),'/Ovrd']);
                              set_param(Bitwise_blk,'Position',[100 20+30*(flt_cnt-1) 140 60+30*(flt_cnt-1)],'MaskValueString',['AND|off|2|bin2dec(','''','11111110','''',')|Stored Integer']);

                    Calibration_content(DD_Calibrations_line,:)={Ovrdval_name%'var_name'	
                                                            '4294967295'%'initial_value'
                                                            '0'%'min_value'	
                                                            '4294967295'%'max_value'
                                                            'uint32'%'data_type'
                                                            'NA'%'uints'
                                                            'DFC ovrdval'%'description'
                                                            };
                    DD_Calibrations_line=DD_Calibrations_line+1;   
                
                    add_line([model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num)],['BitSet',num2str(flt_cnt),'/1'],'Ovrd/1');
                    add_line([model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num)],'Cal/1','Ovrd/2');
                    add_line([model_name,'/',feature_name,'_DFC_Pack/Unit',num2str(roll_num)],'Ovrd/1','Out/1');
                end 
            end
            
            set_param(DFC_blk,'Position',[200+60*(roll_num-1)   (roll_num-1)*640-5   250+60*(roll_num-1)    (roll_num-1)*640+current_group_num*20-5],'ShowName','off');
        end
        
        
        set_param(Bus_blk,'Position',[600+50*(roll_num-1)   -5   610+50*(roll_num-1)    fault_cnt*20-5],'Inputs',num2str(roll_num));
        set_param(Out_blk,'Position',[700+50*(roll_num-1)   fault_cnt*20/2-10   730+50*(roll_num-1)    fault_cnt*20/2+14-10]);
        Inport_line=add_line([model_name,'/',feature_name,'_DFC_Pack'],[fault_name,'/1'],['Unit',num2str(roll_num),'/',num2str(32+roll_cnt)],'autorouting','smart');
            
        % 当roll_cnt=0或者为最后一个故障时,roll_cnt设为-31后重新计数
        % 同时,连接Add_blk和Bus_blk
        if roll_cnt==0||fault_cnt==fault_num
           out_line=add_line([model_name,'/',feature_name,'_DFC_Pack'],['Unit',num2str(roll_num),'/1'],['Bus/',num2str(roll_num)],'autorouting','smart');
           
           out_line_sig_name=[feature_name,'_DFC',num_suffix];
                    set_param(out_line,'Name',out_line_sig_name); 
           roll_cnt=-32;
           roll_num=roll_num+1;  
        end
        roll_cnt=roll_cnt+1;
    end
    add_line([model_name,'/',feature_name,'_DFC_Pack'],'Bus/1',[feature_name,'_DFC/1']);
end
    

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DGM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
waitbar(0.3,waitbar_handle,'DGM模块生成中...');  
%% top subsystem
FltReaction_Pack_ss=add_block('simulink/Commonly Used Blocks/Subsystem',[model_name,'/','DGM']);
Simulink.SubSystem.deleteContents(FltReaction_Pack_ss);
%set_param(FltReaction_Pack_ss,'Position',[-500   0   -300   580],'TreatAsAtomicUnit','On','RTWSystemCode','Nonreusable function','RTWFcnNameOpts','Use subsystem name','RTWFileNameOpts','Use subsystem name');
set_param(FltReaction_Pack_ss,'Position',[500   172   700   768]);

%% DGM输入模块
% 诊断条件输入信号
n_add=1;
Inport_VeAIM_ulvBatVoltRaw=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/COMR_bLvComDiagEn']);
                           set_param(Inport_VeAIM_ulvBatVoltRaw,'Position',[-930    13  -900    27],'ShowName','on');  

       Inport_blk_add=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/COMR_bLvComDiagEn']);
                  set_param(Inport_blk_add,'Position',[250    (n_add)*100+113   280   (n_add)*100+113+14],'ShowName','on');
       Inport_line_add=add_line([model_name],['COMR_bLvComDiagEn/1'],['DGM/',num2str(n_add)],'autorouting','smart');          
                  set_param(Inport_line_add,'Name','COMR_bLvComDiagEn');
       Inport_handle=get_param(Inport_line_add,'SrcPortHandle');
                  set_param(Inport_handle,'MustResolveToSignalObject','on');
                  
       ISP_content(DD_ISP_line,:)={'COMR_bLvComDiagEn'%'var_name'	           %%%新增ISP DD%%%
                                    '0'%'initial_value'
                                    '0'%'min_value'	
                                    '1'%'max_value'
                                    'boolean'%'data_type'
                                    'NA'%'uints'
                                    'NA'%'description'
                                   };
                                   DD_ISP_line=DD_ISP_line+1;
       n_add=n_add+1;                           
                           
Inport_VeDIM_bMainRlyFbRaw=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/BSPR_bKl15WkUp']);
                           set_param(Inport_VeDIM_bMainRlyFbRaw,'Position',[-930    83  -900    97],'ShowName','on');  
                           
       Inport_blk_add=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/BSPR_bKl15WkUp']);
                  set_param(Inport_blk_add,'Position',[250    (n_add)*100+113   280   (n_add)*100+113+14],'ShowName','on');
       Inport_line_add=add_line([model_name],['BSPR_bKl15WkUp/1'],['DGM/',num2str(n_add)],'autorouting','smart');          
                  set_param(Inport_line_add,'Name','BSPR_bKl15WkUp');
       Inport_handle=get_param(Inport_line_add,'SrcPortHandle');
                  set_param(Inport_handle,'MustResolveToSignalObject','on');
                  
       ISP_content(DD_ISP_line,:)={'BSPR_bKl15WkUp'%'var_name'	           %%%新增ISP DD%%%
                                    '0'%'initial_value'
                                    '0'%'min_value'	
                                    '1'%'max_value'
                                    'boolean'%'data_type'
                                    'NA'%'uints'
                                    'NA'%'description'
                                   };
                                   DD_ISP_line=DD_ISP_line+1;
       n_add=n_add+1;
       
Inport_VeDIM_bIgnOnRaw=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/BMCR_bWkUpVCU']);
                           set_param(Inport_VeDIM_bIgnOnRaw,'Position',[-930   118  -900   132],'ShowName','on');
                           
       Inport_blk_add=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/BMCR_bWkUpVCU']);
                  set_param(Inport_blk_add,'Position',[250    (n_add)*100+113   280   (n_add)*100+113+14],'ShowName','on');
       Inport_line_add=add_line([model_name],['BMCR_bWkUpVCU/1'],['DGM/',num2str(n_add)],'autorouting','smart');          
                  set_param(Inport_line_add,'Name','BMCR_bWkUpVCU');
       Inport_handle=get_param(Inport_line_add,'SrcPortHandle');
                  set_param(Inport_handle,'MustResolveToSignalObject','on');
                  
       ISP_content(DD_ISP_line,:)={'BMCR_bWkUpVCU'%'var_name'	           %%%新增ISP DD%%%
                                    '0'%'initial_value'
                                    '0'%'min_value'	
                                    '1'%'max_value'
                                    'boolean'%'data_type'
                                    'NA'%'uints'
                                    'NA'%'description'
                                   };
                                   DD_ISP_line=DD_ISP_line+1;
       n_add=n_add+1;   
       
Inport_VeDIM_bPackB_StatusRaw=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/VCAN_NMMsgRx']);
                           set_param(Inport_VeDIM_bPackB_StatusRaw,'Position',[-790   153  -760   167],'ShowName','on');  
                           
       Inport_blk_add=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/VCAN_NMMsgRx']);
                  set_param(Inport_blk_add,'Position',[250    (n_add)*100+113   280   (n_add)*100+113+14],'ShowName','on');
       Inport_line_add=add_line([model_name],['VCAN_NMMsgRx/1'],['DGM/',num2str(n_add)],'autorouting','smart');          
                  set_param(Inport_line_add,'Name','VCAN_NMMsgRx');
       Inport_handle=get_param(Inport_line_add,'SrcPortHandle');
                  set_param(Inport_handle,'MustResolveToSignalObject','on');
       
       ISP_content(DD_ISP_line,:)={'VCAN_NMMsgRx'%'var_name'	           %%%新增ISP DD%%%
                                    '0'%'initial_value'
                                    '0'%'min_value'	
                                    '1'%'max_value'
                                    'boolean'%'data_type'
                                    'NA'%'uints'
                                    'NA'%'description'
                                   };
                                   DD_ISP_line=DD_ISP_line+1;
       n_add=n_add+1;   
       
Inport_VeBIM_bDTCOFFRaw=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/COMR_stEol']);
                           set_param(Inport_VeBIM_bDTCOFFRaw,'Position',[-790   188  -760   202],'ShowName','on');  
                           
       Inport_blk_add=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/COMR_stEol']);
                  set_param(Inport_blk_add,'Position',[250    (n_add)*100+113   280   (n_add)*100+113+14],'ShowName','on');
       Inport_line_add=add_line([model_name],['COMR_stEol/1'],['DGM/',num2str(n_add)],'autorouting','smart');          
                  set_param(Inport_line_add,'Name','COMR_stEol');
       Inport_handle=get_param(Inport_line_add,'SrcPortHandle');
                  set_param(Inport_handle,'MustResolveToSignalObject','on');
                  
       ISP_content(DD_ISP_line,:)={'COMR_stEol'%'var_name'	           %%%新增ISP DD%%%
                                    '0'%'initial_value'
                                    '0'%'min_value'	
                                    '1'%'max_value'
                                    'boolean'%'data_type'
                                    'NA'%'uints'
                                    'NA'%'description'
                                   };
                                   DD_ISP_line=DD_ISP_line+1;
       n_add=n_add+1;
                           
% Inport_VeBMS_enmBatHvCnctSts=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/VeBMS_enmBatHvCnctSts']);
%                            set_param(Inport_VeBMS_enmBatHvCnctSts,'Position',[-790   273  -760   287],'ShowName','on');  
% Inport_VeMCU_nMtrSpdFdbk_rpm=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/VeMCU_nMtrSpdFdbk_rpm']);
%                            set_param(Inport_VeMCU_nMtrSpdFdbk_rpm,'Position',[-790   323  -760   337],'ShowName','on');  
% Inport_VePMM_enmElecModExt=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/VePMM_enmElecModExt']);
%                            set_param(Inport_VePMM_enmElecModExt,'Position',[-790   373  -760   387],'ShowName','on');  
% Inport_CANWkupRaw=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/VePMM_bCanNMDgFlg']);
%                            set_param(Inport_CANWkupRaw,'Position',[-930    48  -900    62],'ShowName','on');  
                           
% 诊断条件判断
Diag_Cond_ss=add_block('AI_common_lib/Fault Operation/Diag_Cond_BMS',[model_name,'/DGM/','Diag_Cond']);
             set_param(Diag_Cond_ss,'Position',[-670     6  -420   209],'ShowName','on');
Goto_DiagCond_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/','Goto_DiagCond']);
                set_param(Goto_DiagCond_blk,'Position',[-370   104  -265   116],'GotoTag','DiagCond','ShowName','off');  
                
% NRC
% ServNRC_ss=add_block('AI_common_lib/Fault Operation/Diag_Service_Allow',[model_name,'/DGM/','ServAllw']);
%            set_param(ServNRC_ss,'Position',[-670   256  -425   404],'ShowName','on');
           
% 诊断条件连线
add_line([model_name,'/DGM'],['COMR_bLvComDiagEn','/1'],['Diag_Cond','/1']);
add_line([model_name,'/DGM'],['BSPR_bKl15WkUp','/1'],['Diag_Cond','/2']);
add_line([model_name,'/DGM'],['BMCR_bWkUpVCU','/1'],['Diag_Cond','/3']);
add_line([model_name,'/DGM'],['VCAN_NMMsgRx','/1'],['Diag_Cond','/4']);
add_line([model_name,'/DGM'],['COMR_stEol','/1'],['Diag_Cond','/5']);
% add_line([model_name,'/DGM'],['VeBIM_bDTCOFFRaw','/1'],['Diag_Cond','/6']);
add_line([model_name,'/DGM'],['Diag_Cond','/1'],['Goto_DiagCond','/1']);

%NRC连线
% add_line([model_name,'/DGM'],['VeBMS_enmBatHvCnctSts','/1'],['ServAllw','/1'],'autorouting','smart');
% add_line([model_name,'/DGM'],['VeMCU_nMtrSpdFdbk_rpm','/1'],['ServAllw','/2']);
% add_line([model_name,'/DGM'],['VePMM_enmElecModExt','/1'],['ServAllw','/3']);

%% DGM输出相关模块
Max_blk=add_block('simulink/Math Operations/MinMax',[model_name,'/DGM/','Max']);
                set_param(Max_blk,'Position',[490    -6   535   461],'Function','max','Inputs',num2str(feature_num_group),'ShowName','off');
Ovrd_Lvl_blk=add_block('AI_common_lib/Signal Routing/Ovrd_Sig',[model_name,'/DGM/','Ovrd_Lvl']);
            set_param(Ovrd_Lvl_blk,'Position',[650   212   760   248],'MaskValueString',['KeDGM_bFltLvlFlg','|','KeDGM_FltLvlVal']);
                Calibration_content(DD_Calibrations_line,:)={'KeDGM_bFltLvlFlg'%'var_name'	
                                                            '0'%'initial_value'
                                                            '0'%'min_value'	
                                                            '1'%'max_value'
                                                            'boolean'%'data_type'
                                                            'NA'%'uints'
                                                            'FltLvl ovrdflg'%'description'
                                                            };
                DD_Calibrations_line=DD_Calibrations_line+1;
                Calibration_content(DD_Calibrations_line,:)={'KeDGM_FltLvlVal'%'var_name'	
                                                            '0'%'initial_value'
                                                            '0'%'min_value'	
                                                            '4'%'max_value'
                                                            'uint8'%'data_type'
                                                            'NA'%'uints'
                                                            'FltLvl ovrdval'%'description'
                                                            };
                DD_Calibrations_line=DD_Calibrations_line+1;               
                
Bus_FltList_blk=add_block('simulink/Signal Routing/Bus Creator',[model_name,'/DGM/','Bus']);
                set_param(Bus_FltList_blk,'Position',[550   438   570   917],...
                                         'Inputs',num2str(feature_num_group),'ShowName','off');
Bitwise_PT_blk=add_block('simulink/Logic and Bit Operations/Bitwise Operator',[model_name,'/DGM/','Bitwise_PT']);
                set_param(Bitwise_PT_blk,'Position',[490         902         535        1353],...
                                           'MaskValueString',['OR|off|',num2str(feature_num_group),'|bin2dec(','''','11111110','''',')|Stored Integer'],...
                                           'ShowName','off');
Bitwise_AUX_blk=add_block('simulink/Logic and Bit Operations/Bitwise Operator',[model_name,'/DGM/','Bitwise_AUX']);
                set_param(Bitwise_AUX_blk,'Position',[490        1351         535        1804],...
                                           'MaskValueString',['OR|off|',num2str(feature_num_group),'|bin2dec(','''','11111110','''',')|Stored Integer'],...
                                           'ShowName','off');
Ovrd_PT_blk=add_block('AI_common_lib/Signal Routing/Ovrd_Sig',[model_name,'/DGM/','Ovrd_PT']);
            set_param(Ovrd_PT_blk,'Position',[600        1112         710        1148],'MaskValueString',['KeDGM_bFltReactnPtFlg','|','KeDGM_flgFltReactnPtVal']);
                Calibration_content(DD_Calibrations_line,:)={'KeDGM_bFltReactnPtFlg'%'var_name'	
                                                            '0'%'initial_value'
                                                            '0'%'min_value'	
                                                            '1'%'max_value'
                                                            'boolean'%'data_type'
                                                            'NA'%'uints'
                                                            'FID PT ovrdflg'%'description'
                                                            };
                DD_Calibrations_line=DD_Calibrations_line+1;
                Calibration_content(DD_Calibrations_line,:)={'KeDGM_flgFltReactnPtVal'%'var_name'	
                                                            '0'%'initial_value'
                                                            '0'%'min_value'	
                                                            '4294967295'%'max_value'
                                                            'uint32'%'data_type'
                                                            'NA'%'uints'
                                                            'FID PT ovrdval'%'description'
                                                            };
                DD_Calibrations_line=DD_Calibrations_line+1;
Ovrd_AUX_blk=add_block('AI_common_lib/Signal Routing/Ovrd_Sig',[model_name,'/DGM/','Ovrd_AUX']);
            set_param(Ovrd_AUX_blk,'Position',[600        1172         710        1208],'MaskValueString',['KeDGM_bFltReactnAuxFlg','|','KeDGM_flgFltReactnAuxVal']);
               Calibration_content(DD_Calibrations_line,:)={'KeDGM_bFltReactnAuxFlg'%'var_name'	
                                                            '0'%'initial_value'
                                                            '0'%'min_value'	
                                                            '1'%'max_value'
                                                            'boolean'%'data_type'
                                                            'NA'%'uints'
                                                            'FID AUX ovrdflg'%'description'
                                                            };
                DD_Calibrations_line=DD_Calibrations_line+1;
                Calibration_content(DD_Calibrations_line,:)={'KeDGM_flgFltReactnAuxVal'%'var_name'	
                                                            '0'%'initial_value'
                                                            '0'%'min_value'	
                                                            '4294967295'%'max_value'
                                                            'uint32'%'data_type'
                                                            'NA'%'uints'
                                                            'FID AUX ovrdval'%'description'
                                                            };
                DD_Calibrations_line=DD_Calibrations_line+1;
Mux_blk=add_block('simulink/Commonly Used Blocks/Mux',[model_name,'/DGM/','Mux']);
                set_param(Mux_blk,'Position',[840        1101         850        1219],'Inputs','2');

Outport_level_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/','VeDGM_enmVehFltLvl']);
            set_param(Outport_level_blk,'Position',[950   223   980   237]);
Outport_FltList_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/','VaDGM_VehFltList']);
            set_param(Outport_FltList_blk,'Position',[950   673   980   687]);
Outport_FID_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/','VeDGM_flgFltReactn']);
            set_param(Outport_FID_blk,'Position',[950        1153         980        1167]);
    
% 输出信号线    
Level_line_max=add_line([model_name,'/DGM'],'Max/1','Ovrd_Lvl/1');
Level_line=add_line([model_name,'/DGM'],'Ovrd_Lvl/1','VeDGM_enmVehFltLvl/1');
                set_param(Level_line,'Name','VeDGM_enmVehFltLvl'); 
                PT_port_handle=get_param(Level_line,'SrcPortHandle');
                set_param(PT_port_handle,'MustResolveToSignalObject','on');               
FltList_line=add_line([model_name,'/DGM'],'Bus/1','VaDGM_VehFltList/1');
                set_param(FltList_line,'Name','VaDGM_VehFltList'); 
ReactionPT_line_or=add_line([model_name,'/DGM'],'Bitwise_PT/1','Ovrd_PT/1','autorouting','smart');
ReactionPT_line=add_line([model_name,'/DGM'],'Ovrd_PT/1','Mux/1');
                set_param(ReactionPT_line,'Name','VeDGM_flgFltReactnPt'); 
                OvrdPT_port_handle=get_param(ReactionPT_line,'SrcPortHandle');
                set_param(OvrdPT_port_handle,'MustResolveToSignalObject','on');   
ReactionAUX_line_or=add_line([model_name,'/DGM'],'Bitwise_AUX/1','Ovrd_AUX/1','autorouting','smart');
ReactionAUX_line=add_line([model_name,'/DGM'],'Ovrd_AUX/1','Mux/2');
                set_param(ReactionAUX_line,'Name','VeDGM_flgFltReactnAux'); 
                OvrdAUX_port_handle=get_param(ReactionAUX_line,'SrcPortHandle');
                set_param(OvrdAUX_port_handle,'MustResolveToSignalObject','on');  
Reaction_line=add_line([model_name,'/DGM'],'Mux/1','VeDGM_flgFltReactn/1');
                set_param(Reaction_line,'Name','VeDGM_flgFltReactn'); 
%                 PT_port_handle=get_param(Reaction_line,'SrcPortHandle');
%                 set_param(PT_port_handle,'MustResolveToSignalObject','on');

%% Const blk 用于OSP模块中找不到的信号接地或附常值
% DGM_Const_blk=add_block('AI_common_lib/Sources/Const_Src',[model_name,'/DGM/','Const']);
%             set_param(DGM_Const_blk,'Position',[715        1568         810        1612]);
% DGM_Const_outport_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/','VeDGM_Const']);
%             set_param(DGM_Const_outport_blk,'Position',[965        1583         995        1597]);
% Const_line=add_line([model_name,'/DGM'],'Const/1','VeDGM_Const/1'); 

%% 各模块故障处理
for feature_cnt=1:feature_num_group
    roll_cnt=31;
    roll_num=1;
    
    feature_name=feature_cell_group{feature_cnt};
    %提取feature_name(去除数字)
    feature_name_inport=regexprep(feature_name,'\d','');
    %提取group数(去除字母)
    feature_name_num=regexprep(feature_name,'\D','');
    
    try
       Inport_blk=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/',feature_name_inport,'_DFC']);
                set_param(Inport_blk,'Position',[-220    (feature_cnt-1)*60+43    -190    (feature_cnt-1)*60+57],'ShowName','on');
    catch
        Inport_blk=add_block([model_name,'/DGM/',feature_name_inport,'_DFC'],[model_name,'/DGM/',feature_name,'_DFC'],'CopyOption','duplicate');
                set_param(Inport_blk,'Position',[-220    (feature_cnt-1)*60+43    -190    (feature_cnt-1)*60+57],'ShowName','on');
    end
                %由于IOS的诊断在诊断列表中移到最后,IOS诊断的端口号需要设为6才能与现有的架构模型匹配
                if strcmp(feature_name_inport,'IOS')
                    set_param(Inport_blk,'Port','6');
                end
    From_DiagCond_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/DiagCond_From',num2str(feature_cnt)]);
                set_param(From_DiagCond_blk,'Position',[-160    (feature_cnt-1)*60+14    -55    (feature_cnt-1)*60+26],'GotoTag','DiagCond','ShowName','off');
    FltProcess_ss=add_block('simulink/Commonly Used Blocks/Subsystem',[model_name,'/DGM/',feature_name]);
                Simulink.SubSystem.deleteContents(FltProcess_ss);
                set_param(FltProcess_ss,'Position',[0    (feature_cnt-1)*60    150    (feature_cnt-1)*60+60],'ShowName','off');                                        
                set_param(FltProcess_ss,'Mask','On','MaskDisplay',['fprintf(','''',feature_name,'''',')'],...
                                        'TreatAsAtomicUnit','on','RTWSystemCode','Nonreusable function');
                
    Goto_Lvl_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/LvlGoto',num2str(feature_cnt)]);
                set_param(Goto_Lvl_blk,'Position',[200     (feature_cnt-1)*60+4   300    (feature_cnt-1)*60+16],'GotoTag',[feature_name,'_Lvl'],'ShowName','off');   
    Goto_FltList_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/FltListGoto',num2str(feature_cnt)]);
                set_param(Goto_FltList_blk,'Position',[200     (feature_cnt-1)*60+19   300    (feature_cnt-1)*60+31],'GotoTag',[feature_name,'_FltList'],'ShowName','off');  
    Goto_FID_PT_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/FIDGoto_PT',num2str(feature_cnt)]);
                set_param(Goto_FID_PT_blk,'Position',[200     (feature_cnt-1)*60+34   300    (feature_cnt-1)*60+46],'GotoTag',[feature_name,'_FID_PT'],'ShowName','off');  
    Goto_FID_AUX_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/FIDGoto_AUX',num2str(feature_cnt)]);
                set_param(Goto_FID_AUX_blk,'Position',[200     (feature_cnt-1)*60+49   300    (feature_cnt-1)*60+61],'GotoTag',[feature_name,'_FID_AUX'],'ShowName','off');  
    
    From_Lvl_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/LvlFrom',num2str(feature_cnt)]);
                set_param(From_Lvl_blk,'Position',[350     (feature_cnt-1)*15+4   450    (feature_cnt-1)*15+16],'GotoTag',[feature_name,'_Lvl'],'ShowName','off');   
    From_FltList_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/FltListFrom',num2str(feature_cnt)]);
                set_param(From_FltList_blk,'Position',[350      feature_num_group*15+(feature_cnt-1)*15+4   450     feature_num_group*15+(feature_cnt-1)*15+16],'GotoTag',[feature_name,'_FltList'],'ShowName','off');  
    From_FID_PT_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/FIDFrom_PT',num2str(feature_cnt)]);
                set_param(From_FID_PT_blk,'Position',[350     feature_num_group*30+(feature_cnt-1)*15+4   450     feature_num_group*30+(feature_cnt-1)*15+16],'GotoTag',[feature_name,'_FID_PT'],'ShowName','off');  
    From_FID_AUX_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/FIDFrom_AUX',num2str(feature_cnt)]);
                set_param(From_FID_AUX_blk,'Position',[350     feature_num_group*45+(feature_cnt-1)*15+4   450     feature_num_group*45+(feature_cnt-1)*15+16],'GotoTag',[feature_name,'_FID_AUX'],'ShowName','off'); 
    
    [~,fault_num]=size(fault_cell_group{feature_cnt});
    % 如该模块有故障,则生成相应的故障处理
    if fault_num>0
        %计算输入输入故障数
        clear fault_in_cell;
           fault_in_cell=fault_cell_group{feature_cnt}(1,:);
    
        Group_num=ceil(fault_num/32);
        %FltProcess内部输入相关模块
                FltProcess_Inport_DiagCond_blk=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/',feature_name,'/DiagCond_In']);
                                          set_param(FltProcess_Inport_DiagCond_blk,'Position',[-510     3  -480    17],'ShowName','on');
                FltProcess_Goto_DiagCond_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/',feature_name,'/Goto_DiagCond']);
                                          set_param(FltProcess_Goto_DiagCond_blk,'Position',[-360     4  -270    16],'GotoTag','DiagCond','ShowName','off');
                FltProcess_Inport_DFC_blk=add_block('simulink/Commonly Used Blocks/In1',[model_name,'/DGM/',feature_name,'/DFC_In']);
                                          set_param(FltProcess_Inport_DFC_blk,'Position',[-510    (Group_num-1)*10+48  -480    (Group_num-1)*10+62],'ShowName','on');
                FltProcess_BusSlector_blk=add_block('simulink/Commonly Used Blocks/Bus Selector',[model_name,'/DGM/',feature_name,'/BusSelector']);
                                          set_param(FltProcess_BusSlector_blk,'OutputSignals',[feature_name_inport,'_DFC',feature_name_num]);
                                          set_param(FltProcess_BusSlector_blk,'Position',[-415    40  -410    70],'ShowName','off');
                                          
                %各Feature内部输入信号线
                add_line([model_name,'/DGM/',feature_name],['DiagCond_In','/1'],['Goto_DiagCond','/1']);
                add_line([model_name,'/DGM/',feature_name],['DFC_In','/1'],['BusSelector','/1']);
                for Group_cnt=1:Group_num
                    FltProcess_Goto_DFC_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/',feature_name,'/Goto_DFC',num2str(Group_cnt)]);
                                            set_param(FltProcess_Goto_DFC_blk,'Position',[-360     (Group_cnt-1)*20+48  -270    (Group_cnt-1)*20+62],'GotoTag','DFC','ShowName','off');
                    add_line([model_name,'/DGM/',feature_name],['BusSelector','/',num2str(Group_cnt)],['Goto_DFC',num2str(Group_cnt),'/1']);
                end
               %各Feature内部输出相关模块
                FltProcess_Max_blk=add_block('simulink/Math Operations/MinMax',[model_name,'/DGM/',feature_name,'/Max']);
                                            set_param(FltProcess_Max_blk,'Position',[655    0   690    fault_num*10],'Function','max','Inputs',num2str(fault_num),'ShowName','off');
                FltProcess_Bus_Fltlist_blk=add_block('simulink/Signal Routing/Bus Creator',[model_name,'/DGM/',feature_name,'/Bus_FltList']);
                                            set_param(FltProcess_Bus_Fltlist_blk,'Position',[670    fault_num*10   685    fault_num*20],...
                                                        'Inputs',num2str(fault_num),'ShowName','off');
                FltProcess_Bitwise_PT_blk=add_block('simulink/Logic and Bit Operations/Bitwise Operator',[model_name,'/DGM/',feature_name,'/Bitwise_PT']);
                                            set_param(FltProcess_Bitwise_PT_blk,'Position',[655    fault_num*20   690    fault_num*30],...
                                                        'MaskValueString',['OR|off|',num2str(fault_num),'|bin2dec(','''','11111110','''',')|Stored Integer'],'ShowName','off');
                FltProcess_Bitwise_AUX_blk=add_block('simulink/Logic and Bit Operations/Bitwise Operator',[model_name,'/DGM/',feature_name,'/Bitwise_AUX']);
                                            set_param(FltProcess_Bitwise_AUX_blk,'Position',[655    fault_num*30   690    fault_num*40],...
                                                        'MaskValueString',['OR|off|',num2str(fault_num),'|bin2dec(','''','11111110','''',')|Stored Integer'],'ShowName','off');
                                          
                FltProcess_Outport_Lvl_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/',feature_name,'/','Flt_Lvl']);
                                          set_param(FltProcess_Outport_Lvl_blk,'Position',[750    fault_num*5-7   780    fault_num*5+7]);
                FltProcess_Outport_FltList_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/',feature_name,'/','FltList']);
                                          set_param(FltProcess_Outport_FltList_blk,'Position',[750    fault_num*15-7   780    fault_num*15+7]);
                FltProcess_Outport_FID_PT_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/',feature_name,'/','FID_PT']);
                                          set_param(FltProcess_Outport_FID_PT_blk,'Position',[ 750    fault_num*25-7   780    fault_num*25+7]);
                FltProcess_Outport_FID_AUX_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/',feature_name,'/','FID_AUX']);
                                          set_param(FltProcess_Outport_FID_AUX_blk,'Position',[ 750    fault_num*35-7   780    fault_num*35+7]);
                %Process内部输出信号线
                add_line([model_name,'/DGM/',feature_name],['Max','/1'],['Flt_Lvl','/1']);
                add_line([model_name,'/DGM/',feature_name],['Bus_FltList','/1'],['FltList','/1']);
                add_line([model_name,'/DGM/',feature_name],['Bitwise_PT','/1'],['FID_PT','/1']);
                add_line([model_name,'/DGM/',feature_name],['Bitwise_AUX','/1'],['FID_AUX','/1']);
        
    else  %如该模块无故障诊断,需要对生成 terminator和ground
        terminator_PT_blk=add_block('simulink/Commonly Used Blocks/Terminator',[model_name,'/DGM/',feature_name,'/BusSelector']);
                           set_param(terminator_PT_blk,'Position',[20   -15    40     5]); 
        ground_PT_blk=add_block('simulink/Commonly Used Blocks/Ground',[model_name,'/DGM/',feature_name,'/Ground']);
                          set_param(ground_PT_blk,'Position',[315   -10   335    10]); 
        Final_Bitwise_blk=add_block('simulink/Logic and Bit Operations/Bitwise Operator',[model_name,'/DGM/',feature_name,'/FinalBitwise']);
                          set_param(Final_Bitwise_blk,'Position',[460   -19   500    19]); 
        add_line([model_name,'/DGM/',feature_name],'Ground/1','FinalBitwise/1');
    end
    
    %Process 输入信号线
    add_line([model_name,'/DGM'],['DiagCond_From',num2str(feature_cnt),'/1'],[feature_name,'/1']);
    add_line([model_name,'/DGM'],[feature_name,'_DFC/1'],[feature_name,'/2']);
    %Process 输出信号线
    add_line([model_name,'/DGM'],[feature_name,'/1'],['LvlGoto',num2str(feature_cnt),'/1']);
    add_line([model_name,'/DGM'],[feature_name,'/2'],['FltListGoto',num2str(feature_cnt),'/1']);
    add_line([model_name,'/DGM'],[feature_name,'/3'],['FIDGoto_PT',num2str(feature_cnt),'/1']);
    add_line([model_name,'/DGM'],[feature_name,'/4'],['FIDGoto_AUX',num2str(feature_cnt),'/1']);
    %From 输出信号线
    add_line([model_name,'/DGM'],['LvlFrom',num2str(feature_cnt),'/1'],['Max/',num2str(feature_cnt)]);
    Flt_line=add_line([model_name,'/DGM'],['FltListFrom',num2str(feature_cnt),'/1'],['Bus/',num2str(feature_cnt)]);
             set_param(Flt_line,'Name',['DTC_',feature_name]); 
    add_line([model_name,'/DGM'],['FIDFrom_PT',num2str(feature_cnt),'/1'],['Bitwise_PT/',num2str(feature_cnt)]);
    add_line([model_name,'/DGM'],['FIDFrom_AUX',num2str(feature_cnt),'/1'],['Bitwise_AUX/',num2str(feature_cnt)]);
    
    for fault_cnt=1:fault_num
%         fault_name=fault_cell{feature_cnt}{fault_cnt};
           % From(DiagCond)
           From_DiagCond_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/',feature_name,'/From_DiagCond',num2str(fault_cnt)]);
                       set_param(From_DiagCond_blk,'Position',[-220    (fault_cnt-1)*40+4    -130    (fault_cnt-1)*40+16],'GotoTag','DiagCond','ShowName','off');
           % From(DFC)                                        
           From_DFC_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/',feature_name,'/From_DFC',num2str(fault_cnt)]);
                       set_param(From_DFC_blk,'Position',[-220    (fault_cnt-1)*40+24    -130    (fault_cnt-1)*40+36],'GotoTag','DFC','ShowName','off');
           % flt_process
           Process_blk=add_block('AI_common_lib/Fault Operation/DGM_flt_process',[model_name,'/DGM/',feature_name,'/Process',num2str(fault_cnt)]);
                       set_param(Process_blk,'Position',[-30    (fault_cnt-1)*40+2    290    (fault_cnt-1)*40+38],'ShowName','off');
                       set_param(Process_blk,'MaskValueString', [num2str(roll_cnt),'|'...                                   %bit
                                                                 num2str(param_cell_group{feature_cnt}{fault_cnt,1}),'|'...       %add
                                                                 num2str(param_cell_group{feature_cnt}{fault_cnt,2}),'|'...       %sub
                                                                 num2str(param_cell_group{feature_cnt}{fault_cnt,3}),'|'...       %set
                                                                 num2str(param_cell_group{feature_cnt}{fault_cnt,4}),'|'...       %lock
                                                                 num2str(param_cell_group{feature_cnt}{fault_cnt,5}),'|'...       %cond
                                                                 num2str(param_cell_group{feature_cnt}{fault_cnt,6}),'|'...       %level
                                                                 num2str(param_cell_group{feature_cnt}{fault_cnt,7}),'|'...       %reaction_PT
                                                                 num2str(param_cell_group{feature_cnt}{fault_cnt,9})])             %reaction_AUX
          
           % Goto (Max,BitwisePT,BitwiseAUX)
           FltProcess_Goto_Lvl_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/',feature_name,'/Goto_Lvl',num2str(fault_cnt)]);
                                    set_param(FltProcess_Goto_Lvl_blk,'Position',[430     (fault_cnt-1)*40+1  520    (fault_cnt-1)*40+9],'GotoTag',['Lvl',num2str(fault_cnt)],'ShowName','off');
           FltProcess_Goto_FltList_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/',feature_name,'/Goto_FltList',num2str(fault_cnt)]);
                                    set_param(FltProcess_Goto_FltList_blk,'Position',[430     (fault_cnt-1)*40+11  520    (fault_cnt-1)*40+19],'GotoTag',['FltList',num2str(fault_cnt)],'ShowName','off');
           FltProcess_Goto_FID_PT_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/',feature_name,'/Goto_FID_PT',num2str(fault_cnt)]);
                                    set_param(FltProcess_Goto_FID_PT_blk,'Position',[430     (fault_cnt-1)*40+21  520    (fault_cnt-1)*40+29],'GotoTag',['FID_PT',num2str(fault_cnt)],'ShowName','off');
           FltProcess_Goto_FID_AUX_blk=add_block('simulink/Signal Routing/Goto',[model_name,'/DGM/',feature_name,'/Goto_FID_AUX',num2str(fault_cnt)]);
                                    set_param(FltProcess_Goto_FID_AUX_blk,'Position',[430     (fault_cnt-1)*40+31  520    (fault_cnt-1)*40+39],'GotoTag',['FID_AUX',num2str(fault_cnt)],'ShowName','off');
           % From (Max,BitwisePT,BitwiseAUX)
           FltProcess_From_Lvl_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/',feature_name,'/From_Lvl',num2str(fault_cnt)]);
                                    set_param(FltProcess_From_Lvl_blk,'Position',[535     (fault_cnt-1)*10+1  625    (fault_cnt-1)*10+9],'GotoTag',['Lvl',num2str(fault_cnt)],'ShowName','off');
           FltProcess_From_FltList_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/',feature_name,'/From_FltList',num2str(fault_cnt)]);
                                    set_param(FltProcess_From_FltList_blk,'Position',[535     (fault_num)*10+(fault_cnt-1)*10+1  625    (fault_num)*10+(fault_cnt-1)*10+9],'GotoTag',['FltList',num2str(fault_cnt)],'ShowName','off');
           FltProcess_From_FID_PT_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/',feature_name,'/From_FID_PT',num2str(fault_cnt)]);
                                    set_param(FltProcess_From_FID_PT_blk,'Position',[535     (fault_num)*20+(fault_cnt-1)*10+1  625    (fault_num)*20+(fault_cnt-1)*10+9],'GotoTag',['FID_PT',num2str(fault_cnt)],'ShowName','off');
           FltProcess_From_FID_AUX_blk=add_block('simulink/Signal Routing/From',[model_name,'/DGM/',feature_name,'/From_FID_AUX',num2str(fault_cnt)]);
                                    set_param(FltProcess_From_FID_AUX_blk,'Position',[535     (fault_num)*30+(fault_cnt-1)*10+1  625    (fault_num)*30+(fault_cnt-1)*10+9],'GotoTag',['FID_AUX',num2str(fault_cnt)],'ShowName','off');
           % 连线
           add_line([model_name,'/DGM/',feature_name],['From_DiagCond',num2str(fault_cnt),'/1'],['Process',num2str(fault_cnt),'/1']);
           add_line([model_name,'/DGM/',feature_name],['From_DFC',num2str(fault_cnt),'/1'],['Process',num2str(fault_cnt),'/2']);
           
           add_line([model_name,'/DGM/',feature_name],['Process',num2str(fault_cnt),'/1'],['Goto_Lvl',num2str(fault_cnt),'/1']);
           DTC_sig_line=add_line([model_name,'/DGM/',feature_name],['Process',num2str(fault_cnt),'/2'],['Goto_FltList',num2str(fault_cnt),'/1']);
                        set_param(DTC_sig_line,'Name',fault_cell_group{feature_cnt}{2,fault_cnt});  
           % 如果配置DTC存储,则生成DTC数据对象至Outputs栏
           if  ~isnan(param_cell_group{feature_cnt}{fault_cnt,11})   
                DTC_port_handle=get_param(DTC_sig_line,'SrcPortHandle');
                set_param(DTC_port_handle,'MustResolveToSignalObject','on');
                 Outputs_content(Outputs_line,:)={fault_cell_group{feature_cnt}{2,fault_cnt};
                                                '0';
                                                '0';
                                                '1';
                                                'boolean'; 
                                                'NA';                  
                                                '故障存储标志位信号';                   
                                                };
                Outputs_line=Outputs_line+1;

           end
           
           add_line([model_name,'/DGM/',feature_name],['Process',num2str(fault_cnt),'/3'],['Goto_FID_PT',num2str(fault_cnt),'/1']);
           add_line([model_name,'/DGM/',feature_name],['Process',num2str(fault_cnt),'/4'],['Goto_FID_AUX',num2str(fault_cnt),'/1']);
           
           add_line([model_name,'/DGM/',feature_name],['From_Lvl',num2str(fault_cnt),'/1'],['Max/',num2str(fault_cnt)]);
           add_line([model_name,'/DGM/',feature_name],['From_FltList',num2str(fault_cnt),'/1'],['Bus_FltList/',num2str(fault_cnt)]);
           add_line([model_name,'/DGM/',feature_name],['From_FID_PT',num2str(fault_cnt),'/1'],['Bitwise_PT/',num2str(fault_cnt)]);
           add_line([model_name,'/DGM/',feature_name],['From_FID_AUX',num2str(fault_cnt),'/1'],['Bitwise_AUX/',num2str(fault_cnt)]);
           
        
       roll_cnt=roll_cnt-1;

        waitbar((fault_cnt/fault_num),waitbar_handle,[feature_name,' DGM 生成中...']);  
    end
end

%添加FltSigProcess2CAN子系统用于VCU395报文故障处理
% Outport_FltFlg_blk=add_block('simulink/Commonly Used Blocks/Out1',[model_name,'/DGM/','VaDGM_VehFltSigFlg']);
%             set_param(Outport_FltFlg_blk,'Position',[950   778   980   792]);
% FltSigProcess2CAN_blk=add_block('AI_common_lib/Fault Operation/FltSigProcess2CAN',[model_name,'/DGM/','FltSigProcess2CAN']);
%             set_param(FltSigProcess2CAN_blk,'Position',[680   756   870   814]);
% add_line([model_name,'/DGM'],'Bus/1','FltSigProcess2CAN/1');      
% add_line([model_name,'/DGM'],'FltSigProcess2CAN/1','VaDGM_VehFltSigFlg/1','autorouting','smart');      

%%%%%%%%%              

waitbar(0.3+0.03*feature_cnt,waitbar_handle,[feature_name,' DGM 完成!']);  
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%% Post Process %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Inport_line_add=add_line([model_name],['IOS_DFC_Pack/1'],['DGM/',num2str(n_add)],'autorouting','smart');  

waitbar(0.99,waitbar_handle,'DGM生成即将完成...');  

 xlswrite(DD_excel_name,Signal_content,'Signals');
 xlswrite(DD_excel_name,Calibration_content,'Calibrations');
 xlswrite(DD_excel_name,Constant_content,'Constants');
 xlswrite(DD_excel_name,Inputs_content,'Inputs');
 xlswrite(DD_excel_name,Outputs_content,'Outputs');
 xlswrite(DD_excel_name,ISP_content,'ISP');
 
close(waitbar_handle);
save_system(model_name);
close_system(model_name);
msgbox('DGM模型完成!');
end

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%% CodeGen %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if CodeGen
%该部分用于生成故障存储代码obd_config.h obd_vars_auto.c obd_vars_auto.h

end_str='#endif';
end_comment='/*<--------EOF-------->*/';
%% obd_config.h
% 文件头部固定部分
common_head=['/*******************************************************',newline,...
            '* Copyright (C) 2019 AIWAYS SHANGHAI CO., LTD.',newline,...
            '* Generate by SCHEMA DGM Generation Tool',newline,...
            '********************************************************/'];
        
 config_head=['#ifndef __OBD_CONFIG_H__',newline,...
            '#define __OBD_CONFIG_H__',newline,...
            newline,...
            '#include "typedefs.h"',newline,...
            '#include "obd_vars_auto.h"',newline,...
            newline,...
            '/*OBD_CONFIG*/',newline,...
            '#define OBD_FAULT_NAME  \'];
 
 
  % OBD_CAL_CONFIG及OBD_FAULT_NAME内容
  severity_list={'NO_SEVERITY_AVAIL',...
                 'MAINTENANCE_ONLY',...
                 'CHECK_AT_NEXT_HALT',...
                 'CHECK_IMMEDIATELY',...
                 'CHECK_IMMEDIATELY'};
  PRIORITY_list={'FF_PRIORITY_NO',...
                 'FF_PRIORITY_LOW',...
                 'FF_PRIORITY_MEDIUM',...
                 'FF_PRIORITY_HIGH',...
                 'FF_PRIORITY_HIGH'};
 fault_cnt=0;
 for i=1:feature_num
    if ~isempty(fault_cell{i})
      [~,DTC_num]=size(fault_cell{i});
       for j=1:DTC_num
          
          DTC_name=fault_cell{i}{2,j};
          DTC_flag=param_cell{i}{j,11};
          fault_lvl=param_cell{i}{j,6};
          Pcode_str=num2str(param_cell{i}{j,12});
          if strcmp(Pcode_str,'TBD')
              Pcode_str='000000';
          end  
          %如果故障存储栏配置不为空, 则生成相应的DTC信号,否则,该故障不需要存储
          if  ~isnan(DTC_flag)  
              fault_cnt=fault_cnt+1;
                %obd_lv_lvBatOVFlt,\
                OBD_FAULT_NAME_cell{fault_cnt}=['obd_',DTC_name(5:end)];
                %{0xD10017,CHECK_IMMEDIATELY ,FUNC_UINT_1,false ,false ,1,1,2,1,40,FF_PRIORITY_HIGH ,&DTC_lv_lvBatOVFlt},\
                OBD_FAULT_CONFIG_cell{fault_cnt}=['{0x',Pcode_str,',',...     %Pcode
                                            severity_list{fault_lvl+1},',',...
                                            'FUNC_UINT_1',',',...
                                            'false',',',...
                                            'false',',',...
                                            num2str(param_cell{i}{j,13}),',',...   
                                            num2str(param_cell{i}{j,14}),',',...
                                            num2str(param_cell{i}{j,15}),',',...
                                            num2str(param_cell{i}{j,16}),',',...
                                            num2str(param_cell{i}{j,17}),',',...
                                            PRIORITY_list{fault_lvl+1},',',...
                                            '&',DTC_name,'}'];
                %bool DTC_lv_lvBatOVFlt = false;
                OBD_FAULT_C{fault_cnt}=['bool ',DTC_name,' = false;'];
                %extern bool DTC_lv_lvBatOVFlt;
                OBD_FAULT_H{fault_cnt}=['extern bool ',DTC_name,';'];
          end
       end
    end
 end 
  % OBD_FAULT_COUNT_CONFIG
 OBD_FAULT_COUNT_CONFIG=['#define OBD_FAULT_COUNT_CONFIG ',num2str(fault_cnt)];
 
 % OBD_CAL_CONFIG
 OBD_CAL_CONFIG='#define OBD_CAL_CONFIG      \';
 
config_file_name='obd_config.h';
fp_conf = fopen([pwd,'\',config_file_name],'w');

fprintf(fp_conf,'%s\n',common_head);
fprintf(fp_conf,'%s\n',config_head);
for i=1:length(OBD_FAULT_NAME_cell)
    %最后一行不需要加分隔符和换行符 ',\'
    if i==length(OBD_FAULT_NAME_cell)
        fprintf(fp_conf,'%s\n',[OBD_FAULT_NAME_cell{i}]);
    else
        fprintf(fp_conf,'%s\n',[OBD_FAULT_NAME_cell{i},',\']);
    end
end
fprintf(fp_conf,'\n');
fprintf(fp_conf,'%s\n',OBD_FAULT_COUNT_CONFIG);
fprintf(fp_conf,'\n');
fprintf(fp_conf,'%s\n',OBD_CAL_CONFIG);
for i=1:length(OBD_FAULT_NAME_cell)
    %最后一行不需要加分隔符和换行符 ',\'
    if i==length(OBD_FAULT_NAME_cell)
        fprintf(fp_conf,'%s\n',[OBD_FAULT_CONFIG_cell{i}]);
    else
        fprintf(fp_conf,'%s\n',[OBD_FAULT_CONFIG_cell{i},',\']);
    end
end
fprintf(fp_conf,'%s\n',end_str);
fprintf(fp_conf,'%s\n',end_comment);
fclose(fp_conf);
 

%% obd_vars_auto.c
% 变量定义文件头部固定部分
vars_c_head='#include "typedefs.h"';

vars_c_file_name='obd_vars_auto.c';
fp_c = fopen([pwd,'\',vars_c_file_name],'w');

fprintf(fp_c,'%s\n',common_head);
fprintf(fp_c,'%s\n',vars_c_head);
for i=1:length(OBD_FAULT_C)
    fprintf(fp_c,'%s\n',[OBD_FAULT_C{i}]);
end
fprintf(fp_c,'%s\n',end_comment);
fclose(fp_c);

%% obd_vars_auto.h
% 变量声明文件头部固定部分
vars_h_head=['#ifndef __OBD_VARS_AUTO_H__',newline,...
             '#define __OBD_VARS_AUTO_H__',newline,...
             ' #include "typedefs.h"'];
         
vars_h_file_name='obd_vars_auto.h';
fp_h = fopen([pwd,'\',vars_h_file_name],'w');

fprintf(fp_h,'%s\n',common_head);
fprintf(fp_h,'%s\n',vars_h_head);
for i=1:length(OBD_FAULT_H)
    fprintf(fp_h,'%s\n',[OBD_FAULT_H{i}]);
end
fprintf(fp_conf,'%s\n',end_str);
fprintf(fp_h,'%s\n',end_comment);
fclose(fp_h);

end %if CodeGen

end % function end

%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FUN %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [feature,fault_signal,flt_param]=fault_format(data_raw)
[line_num,col_num]=size(data_raw);
% 故障处理定位
for col_cnt=1:col_num
    if strcmp(data_raw{2,col_cnt},'故障定义')
        Def_Start_col= col_cnt;
    elseif strcmp(data_raw{2,col_cnt},'故障诊断')
        Diag_Start_col= col_cnt;
    elseif strcmp(data_raw{2,col_cnt},'故障存储')  
        DTC_Start_col= col_cnt;
    elseif strcmp(data_raw{2,col_cnt},'动力系统故障处理(PT)')
        PT_start_col= col_cnt;
        AUX_start_col= col_cnt+32;
    end
end

feature=[];
feature_num=0;
for i=(8:line_num)%故障处理列表内容从第8行开始
    if ~isnan(data_raw{i,1}) % feature line
        feature_name=data_raw{i,1};
        feature=[feature,{feature_name}];
        feature_num=feature_num+1;
        
        fault_signal{feature_num}=[];
        flt_param{feature_num}=[];
    else   %fault line
        %输入故障名
        fault_name=data_raw{i,5};
        DTC_name=data_raw{i,6};
        fault_signal{feature_num}=[fault_signal{feature_num},{fault_name;DTC_name}];
        
        %确诊次数
        set_num=int16(data_raw{i,Diag_Start_col+2});
        if ~isnumeric(set_num)
            set_num=int16(3);%设置默认确诊次数
        end
            
        %恢复次数
        reset_num=int16(data_raw{i,Diag_Start_col+5});
        if ~isnumeric(reset_num)
            set_num=int16(5);%设置默认恢复次数
        end
        
        %debounce 参数计算
        lmt=int16(lcm(set_num,reset_num));
        inc=int16(lmt/set_num);
        dec=int16(lmt/reset_num);
        
        %故障锁止
        lock_str=data_raw{i,Diag_Start_col+3};
        if strcmp(lock_str,'下电恢复')
            lock=1;
        else
            lock=0;
        end
        
        %故障条件 
        % VCU唤醒,网络唤醒,主继电器,KL15,B包在线
        cond_str=data_raw{i,Diag_Start_col};
        if strcmp(cond_str,'上电2S')
            cond=7;
        elseif strcmp(cond_str,'B包在线')
            cond=6;
        elseif strcmp(cond_str,'KL15')
            cond=5;
        elseif strcmp(cond_str,'主继电器')
            cond=4;
        elseif strcmp(cond_str,'网络唤醒')
            cond=3;
        elseif strcmp(cond_str,'低压正常')
            cond=2;
        else %VCU唤醒
            cond=1;
        end
        
        %故障级别
        %零级故障,一级故障,二级故障,三级故障
        level_str=data_raw{i,Def_Start_col+3};
        if strcmp(level_str,'四级故障')
            level=4;
        elseif strcmp(level_str,'三级故障')
            level=3;
        elseif strcmp(level_str,'二级故障')
            level=2;
        elseif strcmp(level_str,'一级故障')
            level=1;
        else
            level=0;
            
        end
        
        %PT故障处理标定量名 
        reaction_PT_name=['KeDGM_',DTC_name(5:end),'P'];
%         cal_PT{feature_num}=[cal_PT{feature_num},{['KeDGM_',fault_name(8:end),'P']}];
        %PT故障处理标定值
        reaction_PT_raw={data_raw(i,PT_start_col:PT_start_col+31)};
        reaction_PT_val=uint32(0);
        for j=1:length(reaction_PT_raw{1})
            if strcmp(reaction_PT_raw{1}{j},'x')
                reaction_PT_val=reaction_PT_val+bitshift(1,(32-j),'uint32');
            end
        end
%         react_PT{feature_num}=[react_PT{feature_num},reaction_PT_val];
        
        %故障reaction(AUX)
        %AUX故障处理标定量名 
        reaction_AUX_name=['KeDGM_',DTC_name(5:end),'A'];
%         cal_AUX{feature_num}=[cal_AUX{feature_num},{['KeDGM_',fault_name(8:end),'A']}];
        %AUX故障处理标定值
        reaction_AUX_raw={data_raw(i,AUX_start_col:AUX_start_col+31)};
        reaction_AUX_val=uint32(0);
        for j=1:length(reaction_AUX_raw{1})
            if strcmp(reaction_AUX_raw{1}{j},'x')
                reaction_AUX_val=reaction_AUX_val+bitshift(1,(32-j),'uint32');
            end
        end
%         react_AUX{feature_num}=[react_AUX{feature_num},reaction_AUX_val];
        
        DTC_flg=data_raw{i,DTC_Start_col};
        DTC_Pcode=num2str(data_raw{i,DTC_Start_col+1});
        DTC_thr=data_raw{i,DTC_Start_col+2};
        DTC_inc=data_raw{i,DTC_Start_col+3};
        DTC_dec=data_raw{i,DTC_Start_col+4};
        DTC_ConfCycl=data_raw{i,DTC_Start_col+5};
        DTC_AgingCycl=data_raw{i,DTC_Start_col+6};
        
        %故障处理参数设
        flt_param{feature_num}=[flt_param{feature_num};{inc,...
                                                        dec,...
                                                        lmt,...
                                                        lock,...
                                                        cond,...
                                                        level,...
                                                        reaction_PT_name,... 
                                                        reaction_PT_val,...  
                                                        reaction_AUX_name,...
                                                        reaction_AUX_val,...
                                                        DTC_flg,...     %11
                                                        DTC_Pcode,...   %12
                                                        DTC_thr,...     %13
                                                        DTC_inc,...     %14
                                                        DTC_dec,...     %15
                                                        DTC_ConfCycl,...%16
                                                        DTC_AgingCycl}];%17
        
    end
end
end

function [feature,fault_signal,flt_param]=fault_format_group(data_raw)
[line_num,col_num]=size(data_raw);
% 故障处理定位
for col_cnt=1:col_num
    if strcmp(data_raw{2,col_cnt},'故障定义')
        Def_Start_col= col_cnt;
    elseif strcmp(data_raw{2,col_cnt},'故障诊断')
        Diag_Start_col= col_cnt;
    elseif strcmp(data_raw{2,col_cnt},'故障存储')  
        DTC_Start_col= col_cnt;
    elseif strcmp(data_raw{2,col_cnt},'动力系统故障处理(PT)')
        PT_start_col= col_cnt;
        AUX_start_col= col_cnt+32;
    end
end

feature=[];
feature_num=0;
feature_group_num=0;
fault_group_cnt=0;
for i=8:line_num%故障处理列表内容从第8行开始
    % feature line
    if ~isnan(data_raw{i,1})
        fault_group_cnt=0;
        feature_group_num=0;
        feature_name=data_raw{i,1};
        feature=[feature,{feature_name}];
        feature_num=feature_num+1;
        fault_signal{feature_num}=[];
        flt_param{feature_num}=[];
    else   %fault line
        if fault_group_cnt==32
            fault_group_cnt=0;
            feature_group_num=feature_group_num+1;
            feature_name_group=[feature_name,num2str(feature_group_num)];
            feature=[feature,{feature_name_group}];
            feature_num=feature_num+1;
            fault_signal{feature_num}=[];
            flt_param{feature_num}=[];
        end
        %输入故障名
        fault_group_cnt=fault_group_cnt+1;
        fault_name=data_raw{i,5};
        DTC_name=data_raw{i,6};
        fault_signal{feature_num}=[fault_signal{feature_num},{fault_name;DTC_name}];
        
        %确诊次数
        set_num=int16(data_raw{i,Diag_Start_col+2});
        if ~isnumeric(set_num)
            set_num=int16(3);%设置默认确诊次数
        end
            
        %恢复次数
        reset_num=int16(data_raw{i,Diag_Start_col+5});
        if ~isnumeric(reset_num)
            set_num=int16(5);%设置默认恢复次数
        end
        
        %debounce 参数计算
        lmt=int16(lcm(set_num,reset_num));
        inc=int16(lmt/set_num);
        dec=int16(lmt/reset_num);
        
        %故障锁止
        lock_str=data_raw{i,Diag_Start_col+3};
        if strcmp(lock_str,'下电恢复')
            lock=1;
        else
            lock=0;
        end
        
        %故障条件 
        % VCU唤醒,网络唤醒,主继电器,KL15,B包在线
        cond_str=data_raw{i,Diag_Start_col};
        if strcmp(cond_str,'上电2S')
            cond=7;
        elseif strcmp(cond_str,'B包在线')
            cond=6;
        elseif strcmp(cond_str,'KL15')
            cond=5;
        elseif strcmp(cond_str,'主继电器')
            cond=4;
        elseif strcmp(cond_str,'网络唤醒')
            cond=3;
        elseif strcmp(cond_str,'低压正常')
            cond=2;
        else %VCU唤醒
            cond=1;
        end
        
        %故障级别
        %零级故障,一级故障,二级故障,三级故障
        level_str=data_raw{i,Def_Start_col+3};
        if strcmp(level_str,'四级故障')
            level=4;
        elseif strcmp(level_str,'三级故障')
            level=3;
        elseif strcmp(level_str,'二级故障')
            level=2;
        elseif strcmp(level_str,'一级故障')
            level=1;
        else
            level=0;
            
        end
        
        %PT故障处理标定量名 
        reaction_PT_name=['KeDGM_',DTC_name(5:end),'P'];
%         cal_PT{feature_num}=[cal_PT{feature_num},{['KeDGM_',fault_name(8:end),'P']}];
        %PT故障处理标定值
        reaction_PT_raw={data_raw(i,PT_start_col:PT_start_col+31)};
        reaction_PT_val=uint32(0);
        for j=1:length(reaction_PT_raw{1})
            if strcmp(reaction_PT_raw{1}{j},'x')
                reaction_PT_val=reaction_PT_val+bitshift(1,(32-j),'uint32');
            end
        end
%         react_PT{feature_num}=[react_PT{feature_num},reaction_PT_val];
        
        %故障reaction(AUX)
        %AUX故障处理标定量名 
        reaction_AUX_name=['KeDGM_',DTC_name(5:end),'A'];
%         cal_AUX{feature_num}=[cal_AUX{feature_num},{['KeDGM_',fault_name(8:end),'A']}];
        %AUX故障处理标定值
        reaction_AUX_raw={data_raw(i,AUX_start_col:AUX_start_col+31)};
        reaction_AUX_val=uint32(0);
        for j=1:length(reaction_AUX_raw{1})
            if strcmp(reaction_AUX_raw{1}{j},'x')
                reaction_AUX_val=reaction_AUX_val+bitshift(1,(32-j),'uint32');
            end
        end
%         react_AUX{feature_num}=[react_AUX{feature_num},reaction_AUX_val];
        
        DTC_flg=data_raw{i,DTC_Start_col};
        DTC_Pcode=num2str(data_raw{i,DTC_Start_col+1});
        DTC_thr=data_raw{i,DTC_Start_col+2};
        DTC_inc=data_raw{i,DTC_Start_col+3};
        DTC_dec=data_raw{i,DTC_Start_col+4};
        DTC_ConfCycl=data_raw{i,DTC_Start_col+5};
        DTC_AgingCycl=data_raw{i,DTC_Start_col+6};
        
        %故障处理参数设
        flt_param{feature_num}=[flt_param{feature_num};{inc,...
                                                        dec,...
                                                        lmt,...
                                                        lock,...
                                                        cond,...
                                                        level,...
                                                        reaction_PT_name,... 
                                                        reaction_PT_val,...  
                                                        reaction_AUX_name,...
                                                        reaction_AUX_val,...
                                                        DTC_flg,...     %11
                                                        DTC_Pcode,...   %12
                                                        DTC_thr,...     %13
                                                        DTC_inc,...     %14
                                                        DTC_dec,...     %15
                                                        DTC_ConfCycl,...%16
                                                        DTC_AgingCycl}];%17
        
    end
end
end
        
         