function onAfterCodeGen(hCS, buildInfo)
%ONAFTERCODEGEN Hook point for after code generation

%   Copyright 2013-2024 The MathWorks, Inc.
data = codertarget.data.getData(hCS);
targetData = codertarget.targethardware.getTargetHardware(hCS);

h = coder.internal.ModelCodegenMgr.getInstance(getModel(hCS));
xil_info = h.MdlRefBuildArgs.XilInfo;

% Validate if toolchain selected for the hardware board is proper or not
if ~ xil_info.IsSil
    loc_validateToolchainForHardwareBoard(hCS);
end

% "Support long long" parameter should be off when using CLA Task block in
% the model
modelName = get_param(hCS.getModel, 'Name');
mainSrcDir = char(getSourcePaths(buildInfo, 1, 'BuildDir'));
if isfield(data, 'ESB') && isfield(data.ESB, 'ProcessingUnit')
    pu = codertarget.data.getParameterValue(hCS, 'ESB.ProcessingUnit');
else
    pu = '';
end

             
if isequal(get_param(modelName,'ModelReferenceTargetType'),'NONE') && ...
        codertarget.utils.isCLATaskManagerFound(modelName)
    % add it only for top model and only if cla TM is present
    buildInfo.addSourceFiles('cla_task.cla', mainSrcDir, 'SkipForSil');
    buildInfo.addIncludePaths(fullfile('$(CLAMATHLIB_INSTALLDIR)', 'include'));
    rtwprivate('cBeautifierWithOptions', 'cla_task.cla', modelName, false); % beautify the code
end

if (codertarget.resourcemanager.get([],'CLA', 'numCLAs',hCS) > 0) || contains(pu, 'CLA')
    if contains(get_param(modelName, 'TargetLongLongMode'), 'on')
        msg = message('TIC2000:codegen:LongLongNotSupportedWithCLA', get_param(modelName, 'Name'));
        err = MSLException([], msg);
        throw(err);
    end
    rtwprivate('cBeautifierWithOptions', 'cla_task.cla', modelName, false); % beautify the code
    % Replace data types in rtwtypes.h which can cause
    % conflict when used with CLA

    % Add a preference option to remove this data type replacement for
    % rtwtypes
    group = 'MathWorks_TIC2000';
    item  = 'TI_C2000LIB_CLA_EnableDataTypeReplacement';

    if ~ispref(group, item)
        setpref(group,item, 1);
    end

    if ispref(group, item) && getpref(group, item)
        % this pref option is set the first time, and if it is unset by
        % customer, replacement will not take place

        BuildDir = RTW.getBuildDir(modelName);
        rtwTypesPath = fullfile(mainSrcDir, 'rtwtypes.h');

        if (2 == exist(rtwTypesPath, 'file'))
            % found rtwtypes.h in the codegen/build area
        else % else check in sharedutils area
            rtwTypesPath = fullfile(BuildDir.CodeGenFolder, BuildDir.SharedUtilsTgtDir, 'rtwtypes.h');
        end

        if (2 == exist(rtwTypesPath, 'file')) % means, rtwtypes.h not found in sharedutil folder as well
            % check for rtwtypes.h presence
            try
                fid = fopen(rtwTypesPath, 'r');
                dataInFile = fread(fid, '*char')';
                fclose(fid);
                dataInFile = regexprep(dataInFile,'typedef int int8_T', 'typedef short int8_T');
                dataInFile = regexprep(dataInFile,'typedef unsigned int uint8_T', 'typedef unsigned short uint8_T');
                dataInFile = regexprep(dataInFile,'typedef int int16_T', 'typedef short int16_T');
                dataInFile = regexprep(dataInFile,'typedef unsigned int uint16_T', 'typedef unsigned short uint16_T');
                dataInFile = regexprep(dataInFile,'typedef unsigned int boolean_T', 'typedef unsigned short boolean_T');
                fid = fopen(rtwTypesPath, 'w');
                fwrite(fid, dataInFile);
                fclose(fid);
            catch
                % dont throw error
            end
        end        
    end
	% check whether cla_header.h is present in codegen directory and
    % shared directory
    loc_addCLAHeaderFile(hCS, buildInfo);
    % Warning when xcp profiling is on and model contains CLA
    if isequal(get_param(hCS,'CodeExecutionProfiling'), 'on') && ...
            isequal(get_param(hCS,'ExtMode'),'on') && ...
            codertarget.data.isValidParameter(hCS, 'ExtMode.Configuration') && ...
            isequal(codertarget.data.getParameterValue(hCS, 'ExtMode.Configuration'), 'XCP on Serial') &&...
            isequal(get_param(hCS,'IncludeMdlTerminateFcn'),'on')
        MSLDiagnostic('TIC2000:codegen:XCPProfilingWithCLA',modelName).reportAsWarning;
    end
end

% Add mcan.c if MCAN interrupt is used in the model
loc_addMCANSourceFile(hCS, buildInfo);

buildInfo.addLinkFlags(['--define ', data.Runtime.DeviceID],'SkipForSil');
buildInfo.addCompileFlags(['-D', data.Runtime.DeviceID],'SkipForSil');
buildInfo.addDefines(['-D', data.Runtime.DeviceID],'SkipForSil');

current_defines = buildInfo.getDefines;
if any(strcmp(current_defines,'-DMAT_FILE=1'))
    size = codertarget.registry.staticMemorySizeforSDCard(modelName);
    SrcFiles = buildInfo.Src.Files; %Get all source files and find rt_logging.c
    IndexLoggingFile = arrayfun(@(x)strcmp(x.FileName,'rt_logging.c'),SrcFiles); %Find rt_logging.c index
    SrcFiles(IndexLoggingFile) = []; %Remove rt_logging.c
    buildInfo.Src.Files = SrcFiles; % Update buildinfo after removing rt_logging.c

    sppkgroot = codertarget.tic2000.internal.getSpPkgRootDir;
    sharedroot = codertarget.tic2000.internal.getSharedRootDir;
    loggingroot = strrep(matlabshared.file_logging.getRootDir(),'\','/');
    svdDir = matlabshared.svd.internal.getRootDir;
    buildInfo.addIncludePaths(fullfile(loggingroot,'include'));
    buildInfo.addIncludePaths(fullfile(svdDir,'include'));
    buildInfo.addSourceFiles('MW_c28xSPI.c',fullfile(sppkgroot,'src'), 'SkipForSil');
    buildInfo.addSourceFiles('MW_SPI.c',fullfile(sppkgroot,'src'), 'SkipForSil');
    buildInfo.addSourceFiles('MW_c28xGPIO.c',fullfile(sharedroot,'src'), 'SkipForSil');
    buildInfo.addSourceFiles('ff.c',fullfile(sppkgroot,'src'), 'SkipForSil');
    buildInfo.addSourceFiles('ffunicode.c',fullfile(sppkgroot,'src'), 'SkipForSil');
    buildInfo.addSourceFiles('MW_c28xMMC.c',fullfile(sppkgroot,'src'), 'SkipForSil');
    buildInfo.addSourceFiles('ert_targets_logging.c',fullfile(loggingroot,'src'), 'SkipForSil');
    buildInfo.addSourceFiles('c28x_file_logging.c',fullfile(sppkgroot,'src'), 'SkipForSil');
    buildInfo.addDefines(['SD_DISK_ENABLE=', num2str(1)], 'SkipForSil');
    buildInfo.addDefines('MW_SD_STATIC_MEMORY_ENABLE', 'SkipForSil');
    buildInfo.addDefines(['MW_SD_LOW_STACK_MEMORY=', num2str(1)], 'SkipForSil');
    buildInfo.addDefines(['MW_SD_VERBOSE_DISABLE=', num2str(1)], 'SkipForSil');
    buildInfo.addDefines(['MW_SD_STATIC_MEMORY_SIZE=', num2str(size)], 'SkipForSil');
    buildInfo.addDefines(['MW_' data.SDCard.SPIModule], 'SkipForSil');
end

% Add Link flag to remap the memory for DMA access to PWM
if isequal(targetData.SubFamily, '2833x')
    if isfield(data.Runtime, 'DMAAccess') && isequal(data.Runtime.DMAAccess, 1)
        buildInfo.addLinkFlags('--define PWM_DMAACCESS=1','SkipForSil');
    else
        buildInfo.addLinkFlags('--define PWM_DMAACCESS=0','SkipForSil');
    end
end
% Add Link flag to remap the memory for DMA access to PWM
if (isequal(targetData.SubFamily, '2837xD') || ...
        isequal(targetData.SubFamily, '2838x') ||...
        isequal(targetData.SubFamily, '2806x') || ...
        isequal(targetData.SubFamily, '28003x') ||...
        isequal(targetData.SubFamily, '28004x') ||...
        isequal(targetData.SubFamily, '28p65x'))

    if isequal (data.ESB.ProcessingUnit, 'c28xCPU1')
        buildInfo.addLinkFlags('--define CPU1','SkipForSil');
        buildInfo.addCompileFlags('-DCPU1','SkipForSil');
        buildInfo.addDefines('-DCPU1','SkipForSil');
    elseif isequal (data.ESB.ProcessingUnit, 'c28xCPU2')
        buildInfo.addLinkFlags('--define CPU2','SkipForSil');
        buildInfo.addCompileFlags('-DCPU2','SkipForSil');
        buildInfo.addDefines('-DCPU2','SkipForSil');
    elseif isequal (data.ESB.ProcessingUnit, 'CPU1CLA1')
        buildInfo.addLinkFlags('--define CPU1','SkipForSil');
        buildInfo.addCompileFlags('-DCPU1','SkipForSil');
        buildInfo.addDefines('-DCPU1','SkipForSil');
        buildInfo.addLinkFlags('--define CPU1CLA1','SkipForSil');
        buildInfo.addCompileFlags('-DCPU1CLA1','SkipForSil');
        buildInfo.addDefines('-DCPU1CLA1','SkipForSil');
    elseif isequal (data.ESB.ProcessingUnit, 'CPU2CLA1')
        buildInfo.addLinkFlags('--define CPU2','SkipForSil');
        buildInfo.addCompileFlags('-DCPU2','SkipForSil');
        buildInfo.addDefines('-DCPU2','SkipForSil');
        buildInfo.addLinkFlags('--define CPU2CLA1','SkipForSil');
        buildInfo.addCompileFlags('-DCPU2CLA1','SkipForSil');
        buildInfo.addDefines('-DCPU2CLA1','SkipForSil');
    end
end

% Add define statement specific to Profiler
if isequal(strcmp(get_param(hCS,'CodeExecutionProfiling'),'on'),1)
    buildInfo.addDefines('MW_EXEC_PROFILER_ON');
end

if ~isequal(targetData.SubFamily, '2834x')
    if isfield(data.Runtime, 'FlashLoad')
        if isequal(data.Runtime.FlashLoad, 1)
            buildInfo.addLinkFlags('--define BOOT_FROM_FLASH=1','SkipForSil');
            buildInfo.addCompileFlags('-DBOOT_FROM_FLASH=1','SkipForSil');
            buildInfo.addDefines('-DBOOT_FROM_FLASH=1','SkipForSil');
        else
            buildInfo.addLinkFlags('--define BOOT_FROM_FLASH=0','SkipForSil');
            buildInfo.addCompileFlags('-DBOOT_FROM_FLASH=0','SkipForSil');
            buildInfo.addDefines('-DBOOT_FROM_FLASH=0','SkipForSil');
        end
    else
        if ~isempty(strfind(data.TargetHardware, 'boot from flash'))
            buildInfo.addLinkFlags('--define BOOT_FROM_FLASH=1','SkipForSil');
            buildInfo.addCompileFlags('-DBOOT_FROM_FLASH=1','SkipForSil');
            buildInfo.addDefines('-DBOOT_FROM_FLASH=1','SkipForSil');
        else
            buildInfo.addLinkFlags('--define BOOT_FROM_FLASH=0','SkipForSil');
            buildInfo.addCompileFlags('-DBOOT_FROM_FLASH=0','SkipForSil');
            buildInfo.addDefines('-DBOOT_FROM_FLASH=0','SkipForSil');
        end
    end
end

if isfield(codertarget.data.getParameterValue(hCS,'Runtime'),'BootloaderProgrammingSupport')
    if isequal(codertarget.data.getParameterValue(hCS,'Runtime.BootloaderProgrammingSupport'),1) && strcmp(codertarget.targethardware.getTargetRTOS(hCS),'Baremetal')==1
        buildInfo.addLinkFlags('--define BOOT_USING_BL=1','SkipForSil');
        isExtMode = get_param(hCS,'ExtMode');
        if strcmpi(isExtMode,'on') == 1
            msg=message('targetsdk:functions:NoExtModeSupported');
            msg=msg.getString;
            error(msg);
        end

    else
        buildInfo.addLinkFlags('--define BOOT_USING_BL=0','SkipForSil');
    end

else
    buildInfo.addLinkFlags('--define BOOT_USING_BL=0','SkipForSil');
end

% Validate if third party tools are configured with setup screens
if ~ xil_info.IsSil
    loc_verifyThirdPartyTools(hCS,buildInfo);
end

% Add build and link flags specific to accelerators
loc_enableAccelerationFlags(hCS, buildInfo, targetData);

%HRCAP libraries if needed
loc_addHRCAPLibraries(hCS, buildInfo, targetData);

ExternModeSelected = get_param(hCS,'ExtMode');
if isequal(ExternModeSelected, 'on')
    buildInfo.addCompileFlags(' --define="EXTMODE_DISABLEPRINTF" ');
    loc_addExternalModeDefines(hCS, buildInfo);
    loc_writeExternalModeHeaderFile(hCS, buildInfo);
    % Required for EC only
    loc_addSupportToUseRealTimeInExtMode(hCS,buildInfo);
end

% Add debug flags for EABI to generate dwo file with symbol details for all
% global variables for use by CCP - g2381303
modelHandle = get_param(modelName,'Handle');
numCCPs = codertarget.resourcemanager.get(modelHandle, 'CCP', 'numCCPs');
if ((numCCPs > 0) && isequal(get_param(hCS,'Toolchain'), ...
        'Texas Instruments Code Composer Studio - EABI (C2000)'))
    buildInfo.addCompileFlags('--symdebug:dwarf_version=3','SkipForSil');
end

loc_validateOverrunInterruptFunction(hCS);

% calling CLB function to add CLB tool source file
loc_addCLBSourceFile(hCS, buildInfo);

% Add CLA memory configuration linker flags
loc_addCLAMemoryLinkerFlags(hCS, buildInfo);

% Register Config set data
loc_registerConfigSetData(hCS);

% Manage resources for model references
loc_manageModelReferenceResources(hCS, buildInfo);

% DDUX Data logging
loc_logDDUXData(hCS, buildInfo);

% ------------- Functions that needs to be at the end of onAfterCodeGen.
% Do not place anything below these functions -----------------------------

% Function to add dependency build and parallel build flags.
needForceRebuild = false;
loc_addBuildArgumentsAndFlags(hCS, buildInfo, needForceRebuild);

% CCS project creation
if isequal(get_param(hCS,'GenCodeOnly'), 'off') && ~ismac
    try
        if(strcmpi(get_param(modelName,'ModelReferenceTargetType'),'NONE') && ~ xil_info.IsSil && ~xil_info.IsPil)
            %Create a new section in the diagonastic viewer for CCS Project creation
            projectcreation_stage = sldiagviewer.createStage('Code Composer Studio Project','ModelName',buildInfo.getBuildName);
            ccsVersion = codertarget.tic2000.internal.CCSVersionDetect(hCS);
            if ( ccsVersion >= 5)%CCS version should be greater than 5.0.0 for project creation
                % CCS Project creation starts here
                codertarget.tic2000.internal.createCCSproject(hCS,buildInfo);
            else
                sldiagviewer.reportInfo(message('TIC2000:codegen:UnsupportedCCS').getString, 'MessageId', 'TIC2000:codegen:UnsupportedCCS');
            end
            stageCleanup = onCleanup(@() delete(projectcreation_stage));
        else
            % Do not create CCS Project for the referenced model, PIL and SIL models
        end
    catch ME
        sldiagviewer.reportInfo([message('TIC2000:codegen:ProjectCreationFailure').getString, ...
            ME.message],'MessageId', ME.identifier);
    end
end
try
    isESBEnabled = codertarget.utils.isESBEnabled(modelName) && ...
        codertarget.utils.isTaskManagerFound(modelName);
catch
    isESBEnabled = false;
end

pName = 'ESB.ProcessingUnit';
isCLA = codertarget.data.isValidParameter(hCS, pName) && ...
    contains(codertarget.data.getParameterValue(hCS, pName), 'CLA');

if (strcmpi(get_param(modelName,'ModelReferenceTargetType'),'NONE'))
    refModels = find_mdlrefs(modelName ,'MatchFilter',@Simulink.match.internal.filterOutCodeInactiveVariantSubsystemChoices, 'KeepModelsLoaded',true); % look only inside code active choice of VSS
    ipcDriverBlocks = [];
    for i = 1:numel(refModels)
        ipcDriverBlocks = [ipcDriverBlocks;find_system(refModels{i},'MatchFilter',@Simulink.match.internal.filterOutInactiveVariantSubsystemChoices,'regexp','on','BlockType','SubSystem','MaskType','Interprocess.+','ReferenceBlock','procinterlib.+')];
    end
else
    ipcDriverBlocks = find_system(modelName,'MatchFilter',@Simulink.match.internal.filterOutInactiveVariantSubsystemChoices,'regexp','on','BlockType','SubSystem','MaskType','Interprocess.+');
end

if isESBEnabled || isCLA || ~isempty(ipcDriverBlocks)
    soc.tic2000.internal.onAfterCodeGen(hCS, buildInfo);
end
end % end of OnAfterCodeGen

% -------------------------Verify 3P tools---------------------------------
function loc_verifyThirdPartyTools(hCS,buildInfo)
if isequal(get_param(hCS,'GenCodeOnly'), 'off')
    dataTgt = codertarget.targethardware.getTargetHardware(hCS);
    chipFamily = dataTgt.SubFamily;
    % Check tokens for header/source file path
    if (isequal(dataTgt.SubFamily, '2802x') || ...
            isequal(dataTgt.SubFamily, '2803x') || ...
            isequal(dataTgt.SubFamily, '2804x') || ...
            isequal(dataTgt.SubFamily, '2805x') || ...
            isequal(dataTgt.SubFamily, '2806x') || ...
            isequal(dataTgt.SubFamily, '2834x') || ...
            isequal(dataTgt.SubFamily, '28M35x') || ...
            isequal(dataTgt.SubFamily, '28M36x'))
        tokenName = ['DSP' chipFamily '_INSTALLDIR'];
        tpName = 'ControlSUITE';
    elseif isequal(dataTgt.SubFamily, '280x') || ...
            isequal(dataTgt.SubFamily, '281x')
        tokenName = ['DSP' chipFamily '_INSTALLDIR'];
        tpName = 'Source and header files';
    else
        tokenName = 'C2000WAREINSTALLDIR';
        tpName = 'C2000Ware';
    end
    targetInfo = codertarget.attributes.getTargetHardwareAttributes(hCS);
    tokenRequired = 0;
    for tokenIdx = 1:numel(targetInfo.Tokens)
        if isequal(targetInfo.Tokens{tokenIdx}.Name, tokenName)
            tokenRequired = 1;
        end
    end
    targetFolder = codertarget.target.getTargetFolder(hCS);
    attribFileName = codertarget.target.getThirdPartyToolsRegistrationFileName(targetFolder);
    thirdPartyFileDoesNotExists = ~isequal(exist(attribFileName, 'file'), 2);
    if thirdPartyFileDoesNotExists
        msg = message('TIC2000:codegen:ThirdPartyToolNotSetup', get_param(hCS,'Toolchain'));
        err = MSLException([], msg);
        throw(err);
    end
    h = codertarget.thirdpartytools.ThirdPartyToolInfo(attribFileName);
    attributes = h.getThirdPartyTools();
    loc_verifySelectedToolchain(hCS, buildInfo, attributes);
    tokenFound = 0;
    pathValid = 0;
    if exist(attribFileName, 'file') && tokenRequired
        for i=1:numel(attributes)
            if strcmp(attributes{i}{:}.TokenName, tokenName)
                tokenFound = 1;
                % Check for the given token if path registered is valid
                if (exist(attributes{i}{:}.RootFolder, 'dir') == 7)
                    pathValid = 1;
                end
            end
        end
    end
    if ((tokenFound == 0 || pathValid == 0) && tokenRequired)
        msg = message('TIC2000:codegen:ThirdPartyToolNotSetup',tpName);
        err = MSLException([], msg);
        throw(err);
    end
end
end

% ------------------------Verify toolchain selection--------------------------------
function loc_verifySelectedToolchain(hCS, buildInfo, attributes)
toolchain = buildInfo.getBuildToolInfo('ToolchainInfo');
path = toolchain.getBuildTool('C Compiler').getPath;
token = regexp(path,'\$\(([a-zA-Z_][\w_]*)\)', 'tokens','once');
if ~isempty(token)
    macro = toolchain.getMacro(token{1});
    if ~isempty(macro)
        compilerToken = regexp(macro,'\$\(([a-zA-Z_][\w_]*)\)','tokens','once');
        if ~isempty(compilerToken)
            isFound = false;
            for j=1:numel(attributes)
                if isequal(attributes{j}{:}.Category,'toolchain') && ...
                        isequal(attributes{j}{:}.TokenName,compilerToken{1})
                    if (exist(attributes{j}{:}.RootFolder, 'dir') == 7)
                        isFound = true;
                    end
                end
            end
            if ~isFound
                msg = message('TIC2000:codegen:ThirdPartyToolNotSetup', get_param(hCS,'Toolchain'));
                err = MSLException([], msg);
                throw(err);
            end
        end
    end
end
end

%------------------------------LOG DDUX DATA------------------------------
function loc_logDDUXData(hCS, buildInfo)
try
    supportedTags = codertarget.tic2000.internal.getSupportedBlockTags();
    dduxObj = codertarget.tic2000.internal.DataUtility(supportedTags);
    modelName = get_param(hCS.getModel, 'Name');
    modeOfOperation = '';
    if isequal(get_param(modelName,'SimulationMode'), 'external') && ...
            codertarget.data.isValidParameter(hCS, 'ExtMode')
        extModeData = codertarget.data.getParameterValue(hCS, 'ExtMode');
        if isequal(extModeData.Configuration, 'CAN')
            % Register CCP as mode of operation
            modeOfOperation = 'External mode - CAN';
        end
    end
    if ~isempty (modeOfOperation)
        dduxObj.dataUpdate(hCS, buildInfo.ComponentName, modeOfOperation);
    else
        dduxObj.dataUpdate(hCS, buildInfo.ComponentName);
    end
    delete(dduxObj);
catch
end
end

%--- Function to register the Config set peripherals for DDUX data logging---
function loc_registerConfigSetData(hCS)
modelName = get_param(hCS.getModel, 'Name');
modelHandle = get_param(modelName,'Handle');
% DMA
for DMACounter = 1 : 6
    if codertarget.data.isValidParameter(hCS, ['DMA_ch', num2str(DMACounter)])
        DMAData = codertarget.data.getParameterValue(hCS, ['DMA_ch', num2str(DMACounter)]);
        if (DMAData.EnableDMAChannel)
            % register or get the coder target parameter for the DMA
            if codertarget.resourcemanager.isregistered(modelHandle, 'DMA', 'DMAModule')
                DMA = codertarget.resourcemanager.get(modelHandle, 'DMA', 'DMAModule');
            else
                codertarget.resourcemanager.register(modelHandle, 'DMA', 'DMAModule', []);
                DMA = {};
                DMA.DMAChannels = [0, 0, 0, 0, 0, 0];
            end

            if isequal(DMA.DMAChannels(DMACounter), 0)
                codertarget.resourcemanager.increment(modelHandle, 'DMA', 'numDMAs');
                DMA.DMAChannels(DMACounter) = 1;
                codertarget.resourcemanager.set(modelHandle, 'DMA', 'DMAModule', DMA);
            end
        end
    end
end
%EMIF
for EMIFCounter = 1 : 2
    if codertarget.data.isValidParameter(hCS, ['EMIF', num2str(EMIFCounter)])
        EMIFData = codertarget.data.getParameterValue(hCS, ['EMIF', num2str(EMIFCounter)]);
        EMIFEnable = EMIFData.CS0 || EMIFData.CS2;
        if isfield(EMIFData, 'CS3')
            EMIFEnable = EMIFEnable || EMIFData.CS3;
        end
        if isfield(EMIFData, 'CS4')
            EMIFEnable = EMIFEnable || EMIFData.CS4;
        end
        if EMIFEnable
            % register or get the coder target parameter for the EMIF
            if codertarget.resourcemanager.isregistered(modelHandle, 'EMIF', 'EMIFModule')
                EMIF = codertarget.resourcemanager.get(modelHandle, 'EMIF', 'EMIFModule');
            else
                codertarget.resourcemanager.register(modelHandle, 'EMIF', 'EMIFModule', []);
                EMIF = {};
                EMIF.EMIFModule = [0, 0];
            end
            if EMIF.EMIFModule(EMIFCounter) == 0
                EMIF.EMIFModule(EMIFCounter) = 1;
                codertarget.resourcemanager.increment(modelHandle, 'EMIF', 'numEMIFs');
                codertarget.resourcemanager.set(modelHandle, 'EMIF', 'EMIFModule', EMIF);
            end
        end
    end
end
if codertarget.data.isValidParameter(hCS, 'SDCard')
    SDCardData = codertarget.data.getParameterValue(hCS, 'SDCard');
    if SDCardData.Enable
        % Register or get the coder target parameter for the SD Card
        if codertarget.resourcemanager.isregistered(modelHandle, 'SDCard', 'SDCardSPIModule')
            SDCardSPIModule = codertarget.resourcemanager.get(modelHandle, 'SDCard', 'SDCardSPIModule');
        else
            codertarget.resourcemanager.register(modelHandle, 'SDCard', 'SDCardSPIModule', []);
            SDCardSPIModule = {};
        end
        if isempty(SDCardSPIModule)
            SDCardSPIModule = SDCardData.SPIModule;
            codertarget.resourcemanager.set(modelHandle, 'SDCard', 'SDCardSPIModule', SDCardSPIModule);
        end
    end
end
if isequal(get_param(hCS,'CodeExecutionProfiling'), 'on') % Register profiling
    if codertarget.resourcemanager.isregistered(modelHandle, 'Profiling', 'ProfilingEnable')
        profilingEnable = codertarget.resourcemanager.get(modelHandle, 'Profiling', 'ProfilingEnable');
    else
        codertarget.resourcemanager.register(modelHandle, 'Profiling', 'ProfilingEnable', []);
        profilingEnable = {};
    end
    if isempty(profilingEnable)
        profilingEnable = get_param(hCS,'CodeExecutionProfiling');
        codertarget.resourcemanager.set(modelHandle, 'Profiling', 'ProfilingEnable', profilingEnable);
    end
end
if isfield(codertarget.data.getData(hCS),'OverRunDetection')
    overrunDetectionData = codertarget.data.getParameterValue(hCS, 'OverRunDetection');
    if isequal(overrunDetectionData.Enable_overrun_detection, 1)
        codertarget.resourcemanager.set(modelHandle, 'OverrunDetection', 'OverrunDetectionEnable', overrunDetectionData.Enable_overrun_detection);
    end
end
%CLB
if ~isempty(which('codertarget.tic2000.internal.getRootDir')) && codertarget.data.isValidParameter(hCS,'CLB')
    clbData = codertarget.data.getParameterValue(hCS, 'CLB');
    targetData = codertarget.targethardware.getTargetHardware(hCS);
    clbStruct = codertarget.tic2000.pinmap.getCLBData(targetData.SubFamily);
    maxCLBTile = clbStruct.maxTileNum;
    for tileNum = 1:maxCLBTile
        tagName = [ 'TILE' num2str(tileNum)];
        if clbData.(tagName)
            codertarget.resourcemanager.set(modelHandle, 'CLB', tagName, clbData.(tagName));
        end
    end
end
end

% Add External Mode Defines to buildInfo
function loc_addExternalModeDefines(hCS, buildInfo)
data = codertarget.data.getData(hCS);
if isequal(codertarget.data.getParameterValue(hCS,'ExtMode.Configuration'), 'XCP on CAN')
    CANModule = data.ExtMode.CANModule;
    buildInfo.addDefines('-DXCP_ON_CAN');
    buildInfo.addDefines(['-DXCP_CAN_ID_MASTER=',codertarget.attributes.getExtModeData('CANIDCommand', hCS)]);
    buildInfo.addDefines(['-DXCP_CAN_ID_SLAVE=',codertarget.attributes.getExtModeData('CANIDResponse', hCS)]);
    buildInfo.addDefines(['-DXCP_CAN_BAUDRATE=',codertarget.attributes.getExtModeData('BusSpeed', hCS)]);
    % Appending e before CANModule as he structure exists within eCAN as
    % only display name is changed from 'eCAN_A' to 'CAN_A'
    CANModule = ['e' CANModule];
    buildInfo.addDefines(['-DXCP_CAN_SJW=',data.(CANModule).SJW]);
    if isequal(data.(CANModule).SAM, 'Sample_one_time')
        buildInfo.addDefines('-DXCP_CAN_SAMPLE_RATE=SINGLE');
    elseif isequal(data.(CANModule).SAM, 'Sample_three_times')
        buildInfo.addDefines('-DXCP_CAN_SAMPLE_RATE=TRIPLE');
    end
    if isequal(data.(CANModule).SBG, 'Only_falling_edges')
        buildInfo.addDefines('-DXCP_CAN_SYNC_EDGE=SINGLE');
    elseif isequal(data.(CANModule).SBG, 'Both_falling_and_rising_edges')
        buildInfo.addDefines('-DXCP_CAN_SYNC_EDGE=DUAL');
    end
    % Avoid re-initialization if same CAN module blocks present
    modelName = get_param(hCS.getModel, 'Name');
    CAN = codertarget.resourcemanager.get(modelName, 'CAN', 'CANBlocks');
    if ~isequal(CAN,0)
        for i = 1:length(CAN)
            if isequal(CAN{i}.useModule,CANModule)
                buildInfo.addDefines(['MW_SKIP_CAN_INITIALIZATION=', num2str(1)], 'SkipForSil');
                break;
            end
        end
    end
end
end

% Write Pin Info into External Mode Header file
function loc_writeExternalModeHeaderFile(hCS, buildInfo)
data = codertarget.data.getData(hCS);
targetData = codertarget.targethardware.getTargetHardware(hCS);
mainSrcDir = char(getSourcePaths(buildInfo, 1, 'BuildDir'));
HEADERS = sprintf('#include "MW_target_hardware_resources.h"\n');

if isequal(codertarget.data.getParameterValue(hCS,'ExtMode.Configuration'), 'XCP on CAN')
    CANModule = data.ExtMode.CANModule;
    % Appending e before CANModule as he structure exists within eCANas
    % only display name is changed from 'eCAN_A' to 'CAN_A'
    CANModule = ['e' CANModule];
    if isequal(targetData.SubFamily, '2803x') || isequal(targetData.SubFamily, '2805x') || ...
            isequal(targetData.SubFamily, '2806x') || ...
            (isequal(targetData.SubFamily, '280x') && isequal(CANModule, 'eCAN_A'))
        PinAssignment_Rx = 'GPIO30';
        PinAssignment_Tx = 'GPIO31';
    else
        PinAssignment_Rx = data.(CANModule).PinAssignment_Rx;
        PinAssignment_Tx = data.(CANModule).PinAssignment_Tx;
    end

    EXT_CAN_RX_PIN = str2double(PinAssignment_Rx(5:end));
    EXT_CAN_TX_PIN = str2double(PinAssignment_Tx(5:end));

    % Get ECAN Pin Data
    if isequal(targetData.SubFamily, '2807x') || isequal(targetData.SubFamily, '2837xS') || ...
            isequal(targetData.SubFamily, '2837xD')
        pinData = codertarget.tic2000.pinmap.F2837xS.getECANPinData(EXT_CAN_RX_PIN, 'Rx');
        RX_PIN_MUX_VAL = bitor(bitshift(pinData.gpioGCtrlReg, 2), pinData.gpioCtrlReg);
        pinData = codertarget.tic2000.pinmap.F2837xS.getECANPinData(EXT_CAN_TX_PIN, 'Tx');
        TX_PIN_MUX_VAL = bitor(bitshift(pinData.gpioGCtrlReg, 2), pinData.gpioCtrlReg);
    else
        callbackHdl = str2func(['codertarget.tic2000.pinmap.F' targetData.SubFamily '.getECANPinData']);
        pinData = callbackHdl(EXT_CAN_RX_PIN, 'Rx');
        RX_PIN_MUX_VAL = bitor(bitshift(pinData.gpioGCtrlReg, 2), pinData.gpioCtrlReg);
        pinData = callbackHdl(EXT_CAN_TX_PIN, 'Tx');
        TX_PIN_MUX_VAL = bitor(bitshift(pinData.gpioGCtrlReg, 2), pinData.gpioCtrlReg);
    end

    % Generate the rtiostream_can_c28x.h file in the codegeneration folder
    rtioFileWriter = codertarget.tic2000.internal.rtioStreamWriter;
    rtioFileWriter.writeLine(['// Created on ' datestr(now)]);
    rtioFileWriter.writeLine('#ifndef RTIOSTREAM_CAN_C28X_EXT_H_');
    rtioFileWriter.writeLine('#define RTIOSTREAM_CAN_C28X_EXT_H_');
    rtioFileWriter.writeLine('');
    rtioFileWriter.writeLine(HEADERS);
    rtioFileWriter.writeLine(['// CAN Bus Baud Rate = ' num2str(data.(CANModule).BaudRate)]);
    rtioFileWriter.writeLine(['#define EXT_CAN_RX_PIN ' num2str(EXT_CAN_RX_PIN)]);
    rtioFileWriter.writeLine(['#define EXT_CAN_TX_PIN ' num2str(EXT_CAN_TX_PIN)]);
    rtioFileWriter.writeLine('');
    rtioFileWriter.writeLine(['#define RX_PIN_MUX_VAL ' num2str(RX_PIN_MUX_VAL)]);
    rtioFileWriter.writeLine(['#define TX_PIN_MUX_VAL ' num2str(TX_PIN_MUX_VAL)]);
    rtioFileWriter.writeLine('');
    rtioFileWriter.writeLine('#endif');

    contentToWrite = rtioFileWriter.returnContent();
    if (isfile(fullfile(mainSrcDir, 'rtiostream_can_c28x_ext.h')))
        fid = fopen(fullfile(mainSrcDir, 'rtiostream_can_c28x_ext.h'), 'rt');
        oldContents = fread(fid, [1, inf], '*char');
        fclose(fid);
        datePattern = '\d\d\-\w+\-\d\d\d\d\s\d\d\:\d\d\:\d\d';
        rtioFileNeedsUpdate = (~strcmp(regexprep(oldContents, datePattern, ''), ...
            regexprep(contentToWrite, datePattern, '')));
    else
        rtioFileNeedsUpdate = true;
    end

    if rtioFileNeedsUpdate
        %generate the rtiostream_can_c28x_ext.h file in the
        %codegeneration folder if model was updated
        fid = fopen(fullfile(mainSrcDir, 'rtiostream_can_c28x_ext.h'),'w+');
        if ~isequal(fid, -1)
            fprintf(fid, contentToWrite);
            fclose(fid);
        end
    end
elseif isequal(codertarget.data.getParameterValue(hCS,'ExtMode.Configuration'), 'XCP on Serial')

    serialModule = data.ExtMode.SCIModule;
    BaudRate =  data.(serialModule).BaudRate;

    % Specify processor Baud denominator
    % LSPCLK follows method used in ti_c28x_init_sci.tlc

    cpuClockRateMHz = str2double(codertarget.data.getSystemClock(hCS));
    clk_data = codertarget.data.getParameterValue(hCS, 'Clocking');
    lspclk_div = getDividerValueFromString(clk_data.LspclkDiv);

    % SCILBAUD follows method specified by sprug71b
    [SCIBAUD, ~] = calcSCIBaudRatePrescaler(cpuClockRateMHz, lspclk_div, BaudRate);

    SCIHBAUD = floor(SCIBAUD / 256);
    SCILBAUD = SCIBAUD - SCIHBAUD*256;

    PinAssignment_Rx = data.(serialModule).PinAssignment_Rx;
    PinAssignment_Tx = data.(serialModule).PinAssignment_Tx;

    EXT_SCI_RX_PIN = PinAssignment_Rx(5:end);
    EXT_SCI_TX_PIN = PinAssignment_Tx(5:end);
    % For SCI_A, sciModule is 'A'
    sciModule = serialModule(5);
    if isequal(targetData.SubFamily, '2807x') || isequal(targetData.SubFamily, '2837xS') || ...
            isequal(targetData.SubFamily, '2837xD')
        pinData = codertarget.tic2000.pinmap.F2837xS.getSCIPinData(str2double(EXT_SCI_RX_PIN), 'Rx', sciModule);
        RX_PIN_MUX_VAL = bitor(bitshift(pinData.gpioGCtrlReg, 2), pinData.gpioCtrlReg);
        pinData = codertarget.tic2000.pinmap.F2837xS.getSCIPinData(str2double(EXT_SCI_TX_PIN), 'Tx', sciModule);
        TX_PIN_MUX_VAL = bitor(bitshift(pinData.gpioGCtrlReg, 2), pinData.gpioCtrlReg);
    else
        callbackHdl = str2func(['codertarget.tic2000.pinmap.F' targetData.SubFamily '.getSCIPinData']);
        pinData = callbackHdl(str2double(EXT_SCI_RX_PIN), 'Rx', sciModule);
        RX_PIN_MUX_VAL = bitor(bitshift(pinData.gpioGCtrlReg, 2), pinData.gpioCtrlReg);
        pinData = callbackHdl(str2double(EXT_SCI_TX_PIN), 'Tx', sciModule);
        TX_PIN_MUX_VAL = bitor(bitshift(pinData.gpioGCtrlReg, 2), pinData.gpioCtrlReg);
    end

    rtioFileWriter = codertarget.tic2000.internal.rtioStreamWriter;
    rtioFileWriter.writeLine(['// Created on ' datestr(now)]);
    rtioFileWriter.writeLine('#ifndef RTIOSTREAM_SERIAL_C28X_H_');
    rtioFileWriter.writeLine('#define RTIOSTREAM_SERIAL_C28X_H_');
    rtioFileWriter.writeLine('');
    rtioFileWriter.writeLine(HEADERS);
    rtioFileWriter.writeLine(['// Baud Rate = ' num2str(BaudRate)]);
    rtioFileWriter.writeLine(['#define MW_PIL_SCIHBAUD ' num2str(SCIHBAUD)]);
    rtioFileWriter.writeLine(['#define MW_PIL_SCILBAUD ' num2str(SCILBAUD)]);
    rtioFileWriter.writeLine('');
    rtioFileWriter.writeLine(['#define EXT_SCI_RX_PIN ' EXT_SCI_RX_PIN]);
    rtioFileWriter.writeLine(['#define EXT_SCI_TX_PIN ' EXT_SCI_TX_PIN]);
    rtioFileWriter.writeLine('');
    rtioFileWriter.writeLine(['#define RX_PIN_MUX_VAL ' num2str(RX_PIN_MUX_VAL)]);
    rtioFileWriter.writeLine(['#define TX_PIN_MUX_VAL ' num2str(TX_PIN_MUX_VAL)]);
    rtioFileWriter.writeLine('');
    rtioFileWriter.writeLine('#endif');

    contentToWrite = rtioFileWriter.returnContent();

    if (isfile(fullfile(mainSrcDir, 'rtiostream_serial_c28x.h')))
        fid = fopen(fullfile(mainSrcDir, 'rtiostream_serial_c28x.h'), 'rt');
        oldContents = fread(fid, [1, inf], '*char');
        fclose(fid);
        datePattern = '\d\d\-\w+\-\d\d\d\d\s\d\d\:\d\d\:\d\d';
        rtioFileNeedsUpdate = (~strcmp(regexprep(oldContents, datePattern, ''), ...
            regexprep(contentToWrite, datePattern, '')));
    else
        rtioFileNeedsUpdate = true;
    end

    if rtioFileNeedsUpdate
        %generate the rtiostream_serial_c28x.h file in the
        %codegeneration folder if model was updated
        %For BL, rtiostream_c28x.h is statically generated for c2806x with Baud
        % rate of 115200
        fid = fopen(fullfile(mainSrcDir, 'rtiostream_serial_c28x.h'),'w+');
        if ~isequal(fid, -1)
            fprintf(fid, contentToWrite);
            fclose(fid);
        end
    end
end
end

%------------------------------OverrunDetection------------------------------
% PIEnumber and CPUnumber validation with hardware interrupt.
function loc_validateOverrunInterruptFunction(hCS)
if isfield(codertarget.data.getData(hCS),'OverRunDetection')
    overrunDetectionData = codertarget.data.getParameterValue(hCS, 'OverRunDetection');
    if isequal(overrunDetectionData.Enable_overrun_detection,1)&& isfield(overrunDetectionData,'Custom_Logic') &&...
            strcmp(overrunDetectionData.Custom_Logic,'Trigger interrupt')
        % warning if any hardware interrupt block not registered or
        % blocks registered with different interrupt numbers and CPU
        % numbers
        if codertarget.resourcemanager.isregistered('', 'HWINT', 'HWINTBlocks', hCS)
            HWINT = codertarget.resourcemanager.get('', 'HWINT', 'HWINTBlocks', hCS);
            if  ~ismember(str2double(overrunDetectionData.PIE_Number),cell2mat(HWINT.pienumbers)) ||...
                    ~ismember(str2double(overrunDetectionData.CPU_Number),cell2mat(HWINT.interrupts))

                msg = message('TIC2000:codegen:OverrunDetectionInterruptConfiguration',str2double(overrunDetectionData.PIE_Number),str2double(overrunDetectionData.CPU_Number));
                sldiagviewer.reportWarning(msg.getString,'MessageId',msg.Identifier);
            else
                numOfInterrupts = length(HWINT.pienumbers);
                for count = 1:numOfInterrupts
                    if isequal(str2double(overrunDetectionData.CPU_Number),HWINT.interrupts{count}) &&...
                            isequal(str2double(overrunDetectionData.PIE_Number),HWINT.pienumbers{count})

                        if (HWINT.priority{count} >= 40)
                            msg = message('TIC2000:codegen:OverrunDetectionInterruptPriority',HWINT.pienumbers{count},HWINT.interrupts{count},HWINT.priority{count});
                            sldiagviewer.reportWarning(msg.getString,'MessageId',msg.Identifier);
                        end
                    end
                end
            end
        else
            msg = message('TIC2000:codegen:OverrunDetectionInterruptConfiguration',str2double(overrunDetectionData.PIE_Number),str2double(overrunDetectionData.CPU_Number));
            sldiagviewer.reportWarning(msg.getString,'MessageId',msg.Identifier);
        end

    end
end
end

%--- Function to validate toolchain for the selected hardware board ---
function loc_validateToolchainForHardwareBoard(hCS)
% Validate toolchain selection is proper for the selected hardware board
selectedToolChain = get_param(hCS,'Toolchain');
modelName = get_param(hCS.getModel, 'Name');
targetData = codertarget.targethardware.getTargetHardware(hCS);
if isequal(targetData.SubFamily, '2838x') || isequal(targetData.SubFamily, '28p65x')
    requiredToolChain = 'Texas Instruments Code Composer Studio - EABI (C2000)';
else
    requiredToolChain = 'Texas Instruments Code Composer Studio (C2000)';
end
if isequal(get_param(hCS,'GenCodeOnly'), 'off') && ~isequal(selectedToolChain, requiredToolChain)
    msg = message('TIC2000:codegen:TIBoardNotSupportedForToolchain', selectedToolChain, targetData.Name, modelName, requiredToolChain);
    sldiagviewer.reportWarning(msg.getString,'MessageId',msg.Identifier);
end
end

%--Function to add CLB tool source file--
function loc_addCLBSourceFile(hCS, buildInfo)
if ~isempty(which('codertarget.tic2000.internal.getRootDir')) && codertarget.data.isValidParameter(hCS,'CLB')
    mainSrcDir = char(getSourcePaths(buildInfo, 1, 'BuildDir'));
    [sourceFile, headerFile] = codertarget.registry.checkCLBFileEntries(hCS, mainSrcDir);
    if ~isempty(sourceFile)
        [srcFilePath, srcFileName, ext] = fileparts(sourceFile);
        buildInfo.addSourceFiles([srcFileName ext], srcFilePath, 'SkipForSil');
    end
    if ~isempty(headerFile)
        [headerFilePath, ~] = fileparts(headerFile);
        buildInfo.addIncludePaths(['"', headerFilePath, '"']);
    end
end
end

%--Function to add depedency, parallel build flags and arguments fro make file --
function loc_addBuildArgumentsAndFlags(hCS, buildInfo, forceRebuild)

h = coder.internal.ModelCodegenMgr.getInstance(getModel(hCS));
xil_info = h.MdlRefBuildArgs.XilInfo;
modelName = get_param(hCS.getModel, 'Name');
mainSrcDir = char(getSourcePaths(buildInfo, 1, 'BuildDir'));
depUpdateToolInstalled = false;
if isequal(computer('arch'), 'win64')
    [regQueryStatus, regQueryCmdOut] = system('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell"');
    % If valid registry query regQueryStatus
    if(0 == regQueryStatus)
        regQueryCmdTokens = textscan(regQueryCmdOut,'%s','Delimiter','\n','MultipleDelimsAsOne',1);
        regQueryCmdStringArray = regQueryCmdTokens{1, 1};

        for i=1:length(regQueryCmdStringArray)
            if ~isempty(regexp(regQueryCmdStringArray{i}, 'HKEY_LOCAL_MACHINE', 'once'))
                queryString = 'HKEY_LOCAL_MACHINE';
            else
                queryString = '';
            end
            if ~isempty(queryString)
                keyStringForInstall = strrep(regQueryCmdStringArray{i},[queryString '\'],'');
                try
                    depUpdateToolInstalled = winqueryreg(queryString, keyStringForInstall, 'Install');
                    if depUpdateToolInstalled
                        break;
                    end
                catch
                end
            end
        end
    end
else
    [status, cmdout] = system("which sed");
    if ~status && contains(cmdout, 'sed')
        depUpdateToolInstalled = true;
    end
end
forceRebuild = forceRebuild || ~depUpdateToolInstalled;

previousmakeArgs = buildInfo.MakeArgs;
% Remove dependency flags if any
if contains(buildInfo.MakeArgs,'DEPRULES=')
    buildInfo.MakeArgs = regexprep(buildInfo.MakeArgs,'(\s+DEPRULES\=\d+)+','');
end
% Remove force build option
if contains(buildInfo.MakeArgs,'-B')
    buildInfo.MakeArgs = regexprep(buildInfo.MakeArgs,'(\s+\-B)+','');
end
% Remove force build option
if contains(buildInfo.MakeArgs,'-j')
    buildInfo.MakeArgs = regexprep(buildInfo.MakeArgs,'(\s+\-j\d)+\s','');
end
if (forceRebuild)
    % Enable force rebuild if build directory contains any spaces and if
    % existing code was regenerated
    buildInfo.MakeArgs = [buildInfo.MakeArgs ' -B'];
    % Disable dependency rules addition in Makefile
    buildInfo.MakeArgs = [buildInfo.MakeArgs ' DEPRULES=0'];
else
    % Enable dependency rules addition in Makefile
    buildInfo.MakeArgs = [buildInfo.MakeArgs ' DEPRULES=1'];
end

parallelBuild = codertarget.utils.getParallelBuildArg(hCS);
if (parallelBuild ~= 0) && (~ xil_info.IsSil)% SIL mode may use other than gmake and parallel build flag may not work
    buildInfo.MakeArgs = [buildInfo.MakeArgs ' -j' num2str(parallelBuild) ' '];
end

% If the make arguments are changed, then delete the .bat file to ensure it
% is regenerated with updated make arguments
if ~isequal(previousmakeArgs, buildInfo.MakeArgs)
    if isfile(fullfile(mainSrcDir,[modelName '.bat']))
        delete(fullfile(mainSrcDir, [modelName '.bat']));
    end
end
end

%-----------------------CLA LSRAM Memory Configuration------------------------------
% Adds linker flags to configure LSRAM AS CLA program and data memory
function loc_addCLAMemoryLinkerFlags(hCS,buildInfo)
targetData = codertarget.targethardware.getTargetHardware(hCS);
if codertarget.data.isValidParameter(hCS,'CLA')
    lsramStruct = codertarget.registry.claLSRAMMemoryConfig(hCS);
    if(~isempty(lsramStruct))
        if (ismember(targetData.SubFamily,{'28004x','28003x'}))
            % add CPU data start flag only for f28004x and f28003x
            buildInfo.addLinkFlags(['--define CPU_RAMLS_DATA_START=', lsramStruct.cpuDataStart],'SkipForSil');
            buildInfo.addCompileFlags(['-DCPU_RAMLS_DATA_START=',lsramStruct.cpuDataStart],'SkipForSil');
            buildInfo.addDefines(['-DCPU_RAMLS_DATA_START=',lsramStruct.cpuDataStart],'SkipForSil');
            % add CPU data length flag only for f28004x and f28003x
            buildInfo.addLinkFlags(['--define CPU_RAMLS_DATA_LENGTH=', lsramStruct.cpuDataLength],'SkipForSil');
            buildInfo.addCompileFlags(['-DCPU_RAMLS_DATA_LENGTH=', lsramStruct.cpuDataLength],'SkipForSil');
            buildInfo.addDefines(['-DCPU_RAMLS_DATA_LENGTH=', lsramStruct.cpuDataLength],'SkipForSil');
        end
        % add CPU Program start flag
        buildInfo.addLinkFlags(['--define CPU_RAMLS_PROG_START=', lsramStruct.cpuProgStart],'SkipForSil');
        buildInfo.addCompileFlags(['-DCPU_RAMLS_PROG_START=',lsramStruct.cpuProgStart],'SkipForSil');
        buildInfo.addDefines(['-DCPU_RAMLS_PROG_START=',lsramStruct.cpuProgStart],'SkipForSil');
        % add CPU Program length flag
        buildInfo.addLinkFlags(['--define CPU_RAMLS_PROG_LENGTH=', lsramStruct.cpuProgLength],'SkipForSil');
        buildInfo.addCompileFlags(['-DCPU_RAMLS_PROG_LENGTH=', lsramStruct.cpuProgLength],'SkipForSil');
        buildInfo.addDefines(['-DCPU_RAMLS_PROG_LENGTH=', lsramStruct.cpuProgLength],'SkipForSil');
        % Add CLA Program start flag
        buildInfo.addLinkFlags(['--define CLA_RAMLS_PROG_START=', lsramStruct.claProgStart ],'SkipForSil');
        buildInfo.addCompileFlags(['-DCLA_RAMLS_PROG_START=', lsramStruct.claProgStart],'SkipForSil');
        buildInfo.addDefines(['-DCLA_RAMLS_PROG_START=', lsramStruct.claProgStart],'SkipForSil');
        % Add CLA Program length flag
        buildInfo.addLinkFlags(['--define CLA_RAMLS_PROG_LENGTH=', lsramStruct.claProgLength],'SkipForSil');
        buildInfo.addCompileFlags(['-DCLA_RAMLS_PROG_LENGTH=', lsramStruct.claProgLength],'SkipForSil');
        buildInfo.addDefines(['-DCLA_RAMLS_PROG_LENGTH=', lsramStruct.claProgLength],'SkipForSil');
        % Add CLA Data start flag
        buildInfo.addLinkFlags(['--define CLA_RAMLS_DATA_START=', lsramStruct.claDataStart ],'SkipForSil');
        buildInfo.addCompileFlags(['-DCLA_RAMLS_DATA_START=', lsramStruct.claDataStart],'SkipForSil');
        buildInfo.addDefines(['-DCLA_RAMLS_DATA_START=', lsramStruct.claDataStart],'SkipForSil');
        % Add CLA Data length flag
        buildInfo.addLinkFlags(['--define CLA_RAMLS_DATA_LENGTH=', lsramStruct.claDataLength],'SkipForSil');
        buildInfo.addCompileFlags(['-DCLA_RAMLS_DATA_LENGTH=', lsramStruct.claDataLength],'SkipForSil');
        buildInfo.addDefines(['-DCLA_RAMLS_DATA_LENGTH=',lsramStruct.claDataLength],'SkipForSil');
    end
end
end

% --Adds support to use realtime stamp logs during external mode simulation
function loc_addSupportToUseRealTimeInExtMode(hCS,buildInfo)
extModeXcp = isequal(get_param(hCS,'ExtModeMexFile'),'ext_xcp');
enableRealTimeLog = codertarget.data.isValidParameter(hCS,'ExtMode.UseRealtimeStampLogging') ...
    && logical(codertarget.data.getParameterValue(hCS,'ExtMode.UseRealtimeStampLogging'));

if extModeXcp && enableRealTimeLog
    defs = buildInfo.getDefines;
    toremove = contains(defs,'XCP_TIMESTAMP_BASED_ON_SIMULATION_TIME');
    if any(toremove)
        buildInfo.deleteDefines(defs(toremove));
    end
    [timerUnit,timerPreScalar] = codertarget.registry.xcpExternalModeHardwareTimerData(hCS);
    buildInfo.addDefines(['-DMW_TIMER_PRESCALE_FOR_XCP=', num2str(timerPreScalar)], 'SkipForSil');
    buildInfo.addDefines(['-DXCP_TIMESTAMP_UNIT=' timerUnit], 'SkipForSil');
end
end

% ----- Function to save peripheral information of all models to a mat file
% to use the information during code generation and use the defines
% information of all reference model in top model
function loc_manageModelReferenceResources(obj, buildInfo)

if isa(obj, 'Simulink.ConfigSet') || ...
        isa(obj, 'Simulink.ConfigSetRef')
    hCS = obj;
elseif isa(obj,'CoderTarget.SettingsController')
    hCS = obj.getConfigSet;
else
    hCS = getActiveConfigSet(obj);
end

modelName = get_param(hCS.getModel, 'Name');
if isequal(get_param(modelName,'ModelReferenceTargetType'),'NONE')
    % promote defines from ref model to top model
    codeDesc = coder.getCodeDescriptor(modelName);
    refMdls = codeDesc.getReferencedModelNames;
    for i = 1:length(refMdls)
        childMdl = refMdls{i};
        buildDir = RTW.getBuildDir(childMdl);
        buildInfoFile = fullfile(buildDir.CodeGenFolder, buildDir.ModelRefRelativeBuildDir,'buildInfo.mat');
        if isfile(buildInfoFile)
            buildInfoMat = matfile(buildInfoFile);
            defineFlags = getDefines(buildInfoMat.buildInfo);
            toAdd = contains(defineFlags,'-DMW');
            if any(toAdd)
                buildInfo.addDefines(defineFlags(toAdd));
            end
        end
    end
end

peripheralInfo = codertarget.resourcemanager.getAllResources(hCS);
peripheralInfo.isPIL = codertarget.tic2000.internal.isPILCodeGeneration(modelName);
if ~isempty(peripheralInfo)
    save('peripheralInfo.mat','peripheralInfo');
end
end

% ----- Function to add mcan.c if MCAN interrupt is used
function loc_addMCANSourceFile(hCS, buildInfo)
targetData = codertarget.targethardware.getTargetHardware(hCS);
mcanUsedInModel = 0;
if (codertarget.resourcemanager.get([],'TIHWINT', 'numTIHWINT', hCS) > 0)
    HWINT = codertarget.resourcemanager.get('', 'TIHWINT', 'TIHWINTBlocks', hCS);
    for k = 1:length(HWINT)
        if isequal(HWINT{k}.isrNumber, 192) || isequal(HWINT{k}.isrNumber, 193)
            mcanUsedInModel = 1;
            break;
        end
    end
    if(mcanUsedInModel)
        c2000WareDir = codertarget.tic2000.internal.getThirdPartyToken(hCS, 'Texas Instruments C2000Ware');
        buildInfo.addSourceFiles('mcan.c', fullfile(c2000WareDir,'driverlib',['F', targetData.SubFamily],'driverlib'), 'SkipForSil');
    end
end
end


% ----- Function to add HRCAP libraries if used
function loc_addHRCAPLibraries(hCS, buildInfo, targetData)
if isequal(targetData.SubFamily, '2806x') || isequal(targetData.SubFamily, '2803x')
    libPath = [codertarget.tic2000.internal.getThirdPartyToken(hCS, 'Texas Instruments controlSUITE'),...
        '/libs/utilities/hrcap_hccal/type0/v110/lib'];
    if isequal(targetData.SubFamily, '2806x')
        if (2==exist(fullfile(libPath,'HCCal_Type0_V1_fpu32.lib'),'file'))
            buildInfo.addLinkObjects('HCCal_Type0_V1_fpu32.lib',libPath,999,true,true);
            buildInfo.addDefines('-DMW_HCCAL_INCLUDED=0','SkipForSil');
        end
    end
    if isequal(targetData.SubFamily, '2803x')
        if (2==exist(fullfile(libPath,'HCCal_Type0_V1.lib'),'file'))
            buildInfo.addLinkObjects('HCCal_Type0_V1.lib',libPath,999,true,true);
            buildInfo.addDefines('-DMW_HCCAL_INCLUDED=0','SkipForSil');
        end
    end
end
end

% ------- Function to add specific build info parameters for accelerators
% like FastRTS, TMU  etc.
function loc_enableAccelerationFlags(hCS, buildInfo, targetData)
% Enable FastRTS
if isfield(codertarget.data.getParameterValue(hCS,'Runtime'),'EnableFastRTS')
    if isequal(codertarget.data.getParameterValue(hCS,'Runtime.EnableFastRTS'), 1)
        if isequal(targetData.SubFamily, '2833x')
            libPath = [codertarget.tic2000.internal.getThirdPartyToken(hCS, 'Texas Instruments C2000Ware'), ...
                '/libraries/math/FPUfastRTS/c28/lib'];
            if (2 == exist(fullfile(libPath,'rts2800_fpu32_fast_supplement.lib'), 'file'))
                buildInfo.addLinkObjects('rts2800_fpu32_fast_supplement.lib', ...
                    libPath,999,true,true);
                buildInfo.addDefines('-DMW_FAST_RTS_INCLUDED=0','SkipForSil');
            end
        else
            libPath = [codertarget.tic2000.internal.getThirdPartyToken(hCS, 'Texas Instruments controlSUITE'), ...
                '/libs/math/FPUfastRTS/V100/lib'];
            if (2 == exist(fullfile(libPath,'rts2800_fpu32_fast_supplement.lib'), 'file'))
                buildInfo.addLinkObjects('rts2800_fpu32_fast_supplement.lib', ...
                    libPath,999,true,true);
                buildInfo.addDefines('-DMW_FAST_RTS_INCLUDED=0','SkipForSil');
            end
        end
    end
end

% Enable TMU
if isfield(codertarget.data.getParameterValue(hCS,'Runtime'),'EnableTMU')
    if isequal(codertarget.data.getParameterValue(hCS,'Runtime.EnableTMU'), 1)
        % Set TMU flag
        buildInfo.addCompileFlags('--tmu_support=tmu0','SkipForSil');
        % Set Relaxed FP mode
        buildInfo.addCompileFlags('--fp_mode=relaxed','SkipForSil');
    end
end
end

% ------- Function to add cla_header.h to the code gen directory if CLA is
% used and the file has not been created
function loc_addCLAHeaderFile(hCS, buildInfo)
modelName = get_param(hCS.getModel, 'Name');
BuildDir = RTW.getBuildDir(modelName);
mainSrcDir = char(getSourcePaths(buildInfo, 1, 'BuildDir'));
sharedSrcDir = fullfile(BuildDir.CodeGenFolder, BuildDir.SharedUtilsTgtDir);
% Generate the cla_header.h file in the codegeneration folder
rtioFileWriter = codertarget.tic2000.internal.rtioStreamWriter;
rtioFileWriter.writeLine(['// Created on ' datestr(now)]);
rtioFileWriter.writeLine('#ifndef CLAHEADER_H_');
rtioFileWriter.writeLine('#define CLAHEADER_H_');
rtioFileWriter.writeLine('#endif');
contentToWrite = rtioFileWriter.returnContent();
if ~((isfile(fullfile(mainSrcDir, 'cla_header.h'))) ...
        || (isfile(fullfile(sharedSrcDir, 'cla_header.h'))))
    fid = fopen(fullfile(mainSrcDir, 'cla_header.h'), 'w');
    fprintf(fid, contentToWrite);
    fclose(fid);
end
end

% LocalWords:  sharedutils sharedutil dont Sil DMAT buildinfo WAREINSTALLDIR SCIMODULE Delfino
% LocalWords:  INSTALLDIR SPI GPIO ffunicode MMC DMAACCESS DCPU CBlockset DBOOT DEPRULES gmake
% LocalWords:  Bootloader Baremetal targetsdk FP Ufast rts fpu DMW TMU tmu fp Uptodate dep prociolib
% LocalWords:  ccp utils Hdr diagonastic codertarget Sproject EXTMODE xe Interprocess procinterlib
% LocalWords:  DISABLEPRINTF LSPCLK SCILBAUD sprug gpio GCtrl pinmap rtiostream mw ipc
% LocalWords:  SCIHBAUD XCP toolchain
