%%
%%Copyright1994-2017TheMathWorks,Inc.
%%
%%Abstract:GenericS-Functionblocktargetfile
%%
%%CheckifaspecificTLCfileforthiss-functionexists.
%%Ifso,executeitsOOPfunction,otherwise,makean
%%s-functioncall.
%%
 
%implements "S-Function" "C"
 
%%Function:FcnChildSFunctionIndex===========================================
%%Abstract:
%%Thisfunctionmanagestheglobalchilds-functionlist,
%%andreturnstheblock'sS-Functionindex.Theindex
%%isdeterminedbytheglobalvariableNumChildSFunctions
%%
%%Inaddition,thefunctionsetsalltheS-Function'sparameters
%%to"required".
%%
%%block=referencetotheblock
%%
%function FcnChildSFunctionIndex(block) void
  %if !ISFIELD(block, "SFunctionIdx")
    %% register the s-function in the global s-function list
    %addtorecord block SFunctionIdx NumChildSFunctions
    %assign ::CompiledModel.ChildSFunctionList = ...
      ::CompiledModel.ChildSFunctionList + block
    %assign ::CompiledModel.NumChildSFunctions = ...
      ::CompiledModel.NumChildSFunctions + 1
  %endif
  %return block.SFunctionIdx
%endfunction
 
 
%%Function:FcnCopyStatesFromWorkVector======================================
%%Abstract:
%%Functiontocopythes-functionscontiguousstatevectortothe
%%"non-contiguous"modelstatevector.
%%
%%s=childsimstruct
%%xc=continuousstates
%%xd=discretestates
%%
%function FcnCopyStatesFromWorkVector(s, xc, xd) Output
  (void) %<LibGenMemFcnCall("memcpy", xc, "sfcnX", ...
    "ssGetNumContStates(%<s>)*sizeof(real_T)")>;
  (void) %<LibGenMemFcnCall("memcpy", xd, "sfcnX+ssGetNumContStates(%<s>)", ...
    "ssGetNumDiscStates(%<s>)*sizeof(real_T)")>;
%endfunction
 
%%Function:FcnGetAndCheckSFunctionType=======================================
%%Abstract:
%%FunctiontodetermineSFunctionTypefromS-function'sParamSettingsand
%%doessomecheckingbasedonthetype.
%%
%function FcnGetAndCheckSFunctionType(block)
  %with block
    %assign funcName = ParamSettings.FunctionName
    %%
    %% Determine S-function type (e.g. was it remapped, is it inlined, etc.)
    %%
    %% The result of this will be to set
    %% SFunctionType == "C-MEX", "TLC", or "OTHER"
    %%
    %if ParamSettings.Inlined == "yes"
      %assign fileExists = LibBlockSFunctionFileExists(funcName)
      %%
      %if !fileExists
    %assign errTxt = "Unable to locate inlined TLC file: %<funcName>.tlc"
    %<LibBlockReportFatalError(block, errTxt)>
      %endif
      %if ::Accelerator && (funcName == "stateflow")
    %% R12 Beta1: until BlockInstanceData and Terminate functions are
    %% supported, only run MEX-version of stateflow blocks.
    %assign SFunctionType = "OTHER"
      %else
    %%
    %% The S-function has a corresponding TLC file
    %%
    %assign SFunctionType = "TLC"
      %endif
    %elseif ParamSettings.Inlined == "skip"
      %assign SFunctionType = "OTHER"
    %elseif ParamSettings.FunctionType == "C-MEX"
      %assign SFunctionType = "C-MEX"
      %% ERT does not support multi-rate non-inlined sfunctions
      %% in single-tasking mode
      %if SLibIsERTCodeFormat() && TYPE(TID) == "Vector" && ...
    ::CompiledModel.FixedStepOpts.SolverMode == "SingleTasking"
    %if IsModelReferenceTarget()
      %assign target = "Model reference "
    %else
      %assign target = "Embedded-C code format "
    %endif
      %endif
    %else
      %%
      %% The S-function is either a MATLAB File or a Fortran-MEX file.
      %%
      %if ::Accelerator
    %assign SFunctionType = "OTHER"
      %else
    %assign funcType = ParamSettings.FunctionType
    %assign blockName = LibGetFormattedBlockPath(block)
    %assign errTxt = "%<funcType> S-functions " ...
      "without a corresponding TLC file are not supported. " ...
      "You can inline your S-function (%<funcName>) by creating " ...
      "a TLC file for it. You can also remap your S-function to C by " ...
      "creating a corresponding C Mex source file "...
      "and a %<funcName>.tlc file in the same " ...
      "directory as the %<funcType> S-function which contains (on the " ...
      "first line):/n" ...
      " /%/% CallAsCMexLevel1/n" ...
      "or/n" ...
      " /%/% CallAsCMexLevel2/n"
    %<LibBlockReportFatalError(block, errTxt)>
      %endif
    %endif %% Paramsettings
  %endwith %% block
 
  %return SFunctionType
 
%endfunction %% FcnGetAndCheckSFunctionType
 
 
%%Function:FcnCacheRTWGeneratedChildSfcnInfo=================================
%%Abstract:
%%IfamodelcontainsageneratedS-Function,themodelexportfilemust
%%includethechilds-functionexportfileinthecaseifithascustom
%%datatype
%function FcnCacheRTWGeneratedChildSfcnInfo(block, system) void
    %% Cache inlcude export files
    %if !ISFIELD(::CompiledModel, "RTWGeneratedChildSfcnExportFiles")
      %addtorecord ::CompiledModel RTWGeneratedChildSfcnExportFiles ""
      %addtorecord ::CompiledModel RTWGeneratedChildSfcn {}
    %endif
 
    %assign sfcnName = ParamSettings.FunctionName
    %if !ISFIELD(::CompiledModel.RTWGeneratedChildSfcn, sfcnName)
      %% If there are several instances of the same s-function,
      %% cache one export file
      %addtorecord ::CompiledModel.RTWGeneratedChildSfcn %<sfcnName> 1
 
      %assign currExpFiles = ::CompiledModel.RTWGeneratedChildSfcnExportFiles
      %openfile buffer
      #undef S_FUNCTION_NAME
      #if !defined(RTW_GENERATED_SFCN_TUNABLE_PRMS_%<sfcnName>)
      #define RTW_GENERATED_SFCN_TUNABLE_PRMS_%<sfcnName>
      #endif
      %% Include the header file if we're not generating Accelerator
      %% code. The header is needed for any custom types, but we
      %% don't need them for the Accelerator since we'll just be
      %% calling back into Simulink and using the mex file anyway
      %assign raccelUseMexFile = ...
        ::isRAccel && ParamSettings.WillBeDynamicallyLoaded == "yes"
       
      %if !::Accelerator && !raccelUseMexFile
    #include "%<sfcnName>.h"
      %endif
 
      %<currExpFiles>
      %closefile buffer
      %assign ::CompiledModel.RTWGeneratedChildSfcnExportFiles = buffer
      %assign buildDir = FEVAL("rtwprivate", "rtwattic", "getBuildDir")
      %assign errmsgFromCB = FEVAL("RTW.copySfcnModulesToBuildDir","%<sfcnName>", buildDir)
      %if !ISEMPTY(errmsgFromCB)
         %openfile errTxt
         %<errmsgFromCB>
         %closefile errTxt
         %<SLibReportErrorWithIdAndArgs("RTW:tlc:GenericMsg", errTxt)>
      %endif
   %endif
%endfunction %% FcnCacheRTWGeneratedChildSfcnInfo
 
 
%%Function:FcnGenerateCallForRapidAccelerator==========================================================
%function FcnGenerateCallForModelRefSimTarget(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID) Output
   
  %assign simTargetWillUseMexFile = ...
    IsModelReferenceSimTarget() && ParamSettings.WillBeDynamicallyLoaded == "yes"
   
  %if !ISEMPTY(tid)
    %assign methodCall = methodName + "(" + simStruct + ", %<tid>" + ");"
  %else
    %assign methodCall = methodName + "(" + simStruct + ");"
  %endif
 
  %openfile returnBuffer
   
  %if simTargetWillUseMexFile
    {
      static const char* blockSIDForSFcnLoader = "%<blockSID>";
      sfcnLoader_setCurrentSFcnBlockSID(blockSIDForSFcnLoader);
       
      %if ParamSettings.ExpectsSeparateComplexMxArrays == "yes"
        %if !ISEMPTY(tid)
            void (*sfcnMethodPtr)(SimStruct*, int) = %<actualFcnCall>;
            %<SLibWriteSFunctionGuards("if")>
            simTarget_sfcnSeperateComplexCaller_withTID(%<simStruct>, sfcnMethodPtr, %<tid>);
            %<SLibWriteSFunctionGuards("else")>
            sfcnLoader_separateComplexHandler_withTID(%<simStruct>, sfcnMethodPtr, %<tid>);
            %<SLibWriteSFunctionGuards("endif")>
        %else
            void (*sfcnMethodPtr)(SimStruct*) = %<actualFcnCall>;
            %<SLibWriteSFunctionGuards("if")>
            simTarget_sfcnSeperateComplexCaller(%<simStruct>, sfcnMethodPtr);
            %<SLibWriteSFunctionGuards("else")>
            sfcnLoader_separateComplexHandler(%<simStruct>, sfcnMethodPtr);
            %<SLibWriteSFunctionGuards("endif")>
        %endif
 
      %else
        %% ParamSettings.ExpectsSeparateComplexMxArrays = "no"
        %<methodCall>
      %endif
    }
  %else
    %% not using mex file
    %<methodCall>
  %endif
   
  %closefile returnBuffer
   
  %return returnBuffer
   
%endfunction
 
 
%%Function:FcnGenerateCallForRapidAccelerator==========================================================
%function FcnGenerateCallForRapidAccelerator(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID) Output
   
  %assign raccelUseMexFile = ...
    ::isRAccel && ParamSettings.WillBeDynamicallyLoaded == "yes"
 
  %openfile returnBuffer
 
  %if raccelUseMexFile
         
        %if !ISEMPTY(tid)
          %if ISEQUAL(CompiledModel.SolverType, "FixedStep")
        %assign adjustedTID = "(%<tid> <= 1) && gbl_raccel_tid01eq ? 0 : %<tid>"
      %else
        %assign adjustedTID = "%<tid>"
      %endif
      %assign methodCall = methodName + "(" + simStruct + ", %<adjustedTID>" + ");"
    %else
      %assign methodCall = methodName + "(" + simStruct + ");"
    %endif
 
            {
      static const char* blockSIDForSFcnLoader = "%<blockSID>";
      sfcnLoader_setCurrentSFcnBlockSID(blockSIDForSFcnLoader);
 
      %if ParamSettings.ExpectsSeparateComplexMxArrays == "no"
              int_T origSampleHit = ssGetSampleHitPtr(%<simStruct>)[0];
              _ssSetSampleHit(%<simStruct>, 0, 1);
        %<methodCall>
        %if !ISEMPTY(tid) && ISEQUAL(CompiledModel.SolverType, "FixedStep")
          _ssSetSampleHit(%<simStruct>, 0, origSampleHit);
          %endif
        %else
        %% ParamSettings.ExpectsSeparateComplexMxArrays = "yes"
        %if !ISEMPTY(tid)
          void (*sfcnMethodPtr)(SimStruct*, int) = %<actualFcnCall>;
          sfcnLoader_separateComplexHandler_withTID(%<simStruct>, sfcnMethodPtr, %<adjustedTID>);
        %else
          void (*sfcnMethodPtr)(SimStruct*) = %<actualFcnCall>;
          sfcnLoader_separateComplexHandler(%<simStruct>, sfcnMethodPtr);
          %endif
        %endif
      }
     
    %else
    %% not using mex file
 
      %assign commaTID = ISEMPTY(tid) ? "" : ", %<tid>"
      %assign methodCall = methodName + "(" + simStruct + commaTID + ");"
      %<methodCall>
     
    %endif
   
  %closefile returnBuffer
   
  %return returnBuffer
   
%endfunction
 
 
%%Function:FcnGenerateCallForTargetThatCanUseSFcnMexFile===============================================
%%Abstract:
%%Inrapidacceleratormode,theformatofans-functionmodelmethodcall(mdlOutputsetc.)
%%dependsonwhetherornotthes-functionisdynamicallyloadedviaitsmexfile,orwhether
%%thes-functionsourcediscompiledintotherapidacceleratorexecutable.Inthefirstcase,
%%thes-function'ssimstructparameterpointermustberedirectedtoanarrayofactual
%%mxArraysbeforethemodelmethodcallismade(s-functionparametersarestoredasCdatatypes
%%inrapidacceleratorgeneratedcode,notasactualmxArrays;dynamicallyloadeds-functions
%%expectparametersintheformofactualmxarrays).
 
%function FcnGenerateCallForTargetThatCanUseSFcnMexFile(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID) Output
   
  %if ::isRAccel
    %<FcnGenerateCallForRapidAccelerator(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID)>
  %elseif IsModelReferenceSimTarget()
    %<FcnGenerateCallForModelRefSimTarget(simStruct, sFcnIdx, methodName, tid, actualFcnCall, blockSID)>
  %endif
   
%endfunction
 
 
%%Function:BlockInstanceSetup===============================================
%%Abstract:
%%0)AddType/Levelcombovariableforcomment
%%1)Addafreebufferifusingmalloc
%%2)Ifit'saStateflow(notinAccelerator)/InlinedS-function,then
%%calltheBlockInstanceSetupfunction.
%%3)Ifit'saC-MexS-function,thenregisterthes-functioninthe
%%globalchildindextable
%%4)Otherwise,it'saMATLABfileorFortran-Mexfile.Ifthenumberof
%%outputsisgreaterthanzero,exit.
%%
%function BlockInstanceSetup(block, system) void
 
  %assign funcName = ParamSettings.FunctionName
  %assign str = ""
 
  %if LibSFunctionLevel() == "RTWLevel2"
    %% Cache #include child s-function export files
    %<FcnCacheRTWGeneratedChildSfcnInfo(block, system)>
  %endif
  %if LibSFunctionLevel() == "RTWLevel2"
    %assign str = "RTW Generated "
  %endif
  %assign TypeLevel = "%<str>Level%<ParamSettings.FunctionLevel> %<Type>"
  %assign block = block + TypeLevel
 
  %assign sFunctionType = FcnGetAndCheckSFunctionType(block)
  %addtorecord block SFunctionType sFunctionType
 
  %if sFunctionType == "TLC"
     %% Mark destination system when fcn-call branches. This information is used to
     %% issue error message when obsolete TLC function LibExecuteFcnXXX and LibXXXFCSS
     %% are incorrectly used in customer TLC files.
    %if SLibSfcnHasBranchFcnCall(block)
      %% Go over each element that invokes function-call
      %foreach callIdx = block.NumSFcnSysOutputCalls
        %assign nCalledFC = block.SFcnSystemOutputCallMappingInfo[callIdx].NumOfCalledFC
        %if nCalledFC > 1 %% This elements invokes a branched function-call
          %assign recIdx = block.SFcnSystemOutputCallMappingInfo[callIdx].StartingIdx
          %foreach fcIdx = nCalledFC
            %assign blockToCall = block.SFcnSystemOutputCall[recIdx].BlockToCall
         
            %assert !ISEQUAL(blockToCall, "unconnected")
            %assign sysIdx = blockToCall[0]
            %assign blkIdx = blockToCall[1]
            %assign calledBlock = ::CompiledModel.System[sysIdx].Block[blkIdx]
             
            %if calledBlock.Type == "SubSystem"
              %with calledBlock
                %assign sysIdx = LibBlockParamSetting("Subsystem", "SystemIdx")
                %assign calledSys = System[sysIdx]
              %endwith
              %if !ISFIELD(calledSys, "IsBranchedSys")
                %addtorecord calledSys IsBranchedSys TLC_TRUE
              %endif %% if !ISFIELD(calledSys, "IsBranchedSys")
            %endif %% if calledBlock.Type == "SubSystem"
 
            %assign recIdx = recIdx + 1 %% Update the record index
          %endforeach %% foreach fcIdx = nCalledFC
        %endif %% if nCalledFC > 1
      %endforeach %% foreach callIdx = block.NumSFcnSysOutputCalls
    %endif %% if SLibSfcnHasBranchFcnCall(block)
 
    %if SLibIsMainCodeGenPhase()
      %assign origModuleIdx = ::CurrentModuleIdx
      %assign ::CurrentModuleIdx = system.CGIRModuleIdx
      %<GENERATE_TYPE(block, "BlockInstanceSetup", funcName, system)>
      %assign ::CurrentModuleIdx = origModuleIdx
    %else
      %<GENERATE_TYPE(block, "BlockInstanceSetup", funcName, system)>
    %endif
  %elseif sFunctionType == "C-MEX" || (sFunctionType == "OTHER" && ...
    ::Accelerator)
    %%
    %% The S-function is a C-MEX file (without a TLC file)
    %%
 
    %assign ps = ParamSettings
    %if ps.FunctionLevel == 1
      %%
      %% By default, most level 1 S-functions are called.
      %%
      %assign InitializeSizesEmpty = 0
      %assign InitializeSampleTimesEmpty = 0
      %assign InitializeConditionsEmpty = 0
      %assign StartEmpty = 0
      %assign SetupRuntimeResourcesEmpty = 1
      %assign OutputsEmpty = 0
      %assign UpdateEmpty = 0
      %assign DerivativesEmpty = 0
      %assign ProjectionEmpty = 0
      %assign ForcingFunctionEmpty = 0
      %assign MassMatrixEmpty = 0
      %assign ZeroCrossingsEmpty = 1
      %assign EnableEmpty = 0
      %assign DisableEmpty = 0
      %assign TerminateEmpty = 0
      %assign CleanupRuntimeResourcesEmpty = 1
    %else
      %%
      %% By default, all level 2 S-functions are not called.
      %%
      %assign InitializeSizesEmpty = 1
      %assign InitializeSampleTimesEmpty = 1
      %assign InitializeConditionsEmpty = 1
      %assign SetupRuntimeResourcesEmpty = 1
      %assign StartEmpty = 1
      %assign OutputsEmpty = 1
      %assign UpdateEmpty = 1
      %assign DerivativesEmpty = 1
      %assign ProjectionEmpty = 1
      %assign ForcingFunctionEmpty = 1
      %assign MassMatrixEmpty = 1
      %assign ZeroCrossingsEmpty = 1
      %assign EnableEmpty = 1
      %assign DisableEmpty = 1
      %assign TerminateEmpty = 1
      %assign CleanupRuntimeResourcesEmpty = 1
    %endif
    %assign ps = ps + InitializeSizesEmpty
    %assign ps = ps + InitializeSampleTimesEmpty
    %assign ps = ps + InitializeConditionsEmpty
    %assign ps = ps + SetupRuntimeResourcesEmpty
    %assign ps = ps + StartEmpty
    %assign ps = ps + OutputsEmpty
    %assign ps = ps + UpdateEmpty
    %assign ps = ps + DerivativesEmpty
    %assign ps = ps + ProjectionEmpty
    %assign ps = ps + ForcingFunctionEmpty
    %assign ps = ps + MassMatrixEmpty
    %assign ps = ps + ZeroCrossingsEmpty
    %assign ps = ps + EnableEmpty
    %assign ps = ps + DisableEmpty
    %assign ps = ps + TerminateEmpty
    %assign ps = ps + CleanupRuntimeResourcesEmpty
    %%
    %% Determine if states are discontiguous and attach it to the block.
    %% This knowledge is required later in code generation, so just
    %% compute it once. Note that this is only relevant for level 2
    %% S-functions
    %%
    %if ps.FunctionLevel == 1
      %assign numDiscStates = DiscStates[0]
      %assign numContStates = ContStates[0]
      %assign nStates = numDiscStates + numContStates
      %assign statesDiscontiguous = (numDiscStates > 0) && (numContStates > 0)
    %else
      %%
      %% Pinpoint exactly which functions are to be called. (Note that
      %% an mdlRTW function is illegal since it is expected that the
      %% S-function has a corresponding TLC file).
      %%
      %foreach idx = SIZE(ps.SFcnmdlRoutines, 1)
        %switch ps.SFcnmdlRoutines[idx]
          %case "mdlInitializeSizes"
            %assign ps.InitializeSizesEmpty = 0
            %break
          %case "mdlInitializeSampleTimes"
            %assign ps.InitializeSampleTimesEmpty = 0
            %break
          %case "mdlInitializeConditions"
            %assign ps.InitializeConditionsEmpty = 0
            %break
          %case "mdlSetupRuntimeResources"
            %assign ps.SetupRuntimeResourcesEmpty = 0
            %break
          %case "mdlStart"
            %assign ps.StartEmpty = 0
            %break
          %case "mdlOutputs"
            %assign ps.OutputsEmpty = 0
            %break
          %case "mdlUpdate"
            %assign ps.UpdateEmpty = 0
            %break
          %case "mdlDerivatives"
            %assign ps.DerivativesEmpty = 0
            %break
          %case "mdlProjection"
            %assign ps.ProjectionEmpty = 0
            %break
          %case "mdlForcingFunction"
            %assign ps.ForcingFunctionEmpty = 0
            %break
          %case "mdlMassMatrix"
            %assign ps.MassMatrixEmpty = 0
            %break
          %case "mdlZeroCrossings"
            %assign ps.ZeroCrossingsEmpty = 0
            %break
          %case "mdlTerminate"
            %assign ps.TerminateEmpty = 0
            %break
          %case "mdlCleanupRuntimeResources"
            %assign ps.CleanupRuntimeResourcesEmpty = 0
            %break
          %case "mdlEnable"
            %assign ps.EnableEmpty = 0
            %break
          %case "mdlDisable"
            %assign ps.DisableEmpty = 0
            %break
          %case "mdlRTW"
            %assign raccelUseMexFile = ...
              ::isRAccel && ParamSettings.WillBeDynamicallyLoaded == "yes"
               
        %if (LibSFunctionLevel() == "RTWLevel2") || ::Accelerator || IsModelReferenceSimTarget() || raccelUseMexFile
              %break
        %endif
            %assign errTxt = "This S-function block must have a " ...
              "corresponding TLC file since it has an mdlRTW() function."
            %<LibBlockReportError(block, errTxt)>
        %endswitch
      %endforeach
      %%
      %% States are contiguous by design
      %%
      %assign statesDiscontiguous = 0
    %endif
    %addtorecord block StatesDiscontiguous statesDiscontiguous
    %%
    %% register S-function in global index table
    %%
    %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
 
    %% Loop over the Parameter Records and look for matrix parameters.
    %foreach paramIdx = Parameters[0]
      %assign param = Parameter[paramIdx]
      %% Go through each parameter in the AST and mark it as a MatlabMatrix if
      %% it is a matrix. Note that we mark it in the Parameter record in the
      %% ModelParameters table, NOT in the block Parameter record.
      %assign param_array = SLibGetAllASTParamsForBlockParam(param)
      %foreach mdlParamIdx = SIZE(param_array, 1)
        %assign mdlParam = ModelParameters.Parameter[param_array[mdlParamIdx]]
        %if (LibGetDataTypeIdAliasedThruToFromId(LibGetRecordDataTypeId(mdlParam)) != tSS_DOUBLE || ...
          LibGetRecordIsComplex(mdlParam)) && !::Accelerator && !IsModelReferenceTarget()
          %assign errTxt = "This non-inlined C-MEX Block " ...
            "has non-double and(or) complex parameters. The Real-Time " ...
            "Workshop does not support C-MEX S-Functions " ...
            "with non-double or complex parameters without a "...
            "corresponding TLC file."
          %<LibBlockReportFatalError(block, errTxt)>
        %endif
        %assign prmSize = SLibGetSizeOfValueFromParamRec(mdlParam)
        %if prmSize[0] > 1
          %% This is a Matrix Parameter of a non-inlined C-MEX S-Function.
          %% It needs to be declared in column-major form (Matlab style).
          %<LibAddIdentifier(mdlParam, "MatlabMatrix", 1)>
        %endif
        %assign mdlParam.WasAccessedAsVariable = 1
      %endforeach
    %endforeach
 
  %endif
 
%endfunction %% BlockInstanceSetup
 
 
%%Function:BlockTypeSetup===================================================
%%Abstract:
%%PerformS-functionBlockTypeSetupfunction
%%
%function BlockTypeSetup(block, system) void
  %assign funcName = ParamSettings.FunctionName
  %% NOTE: sFunctionType is not from the Block record.
  %assign sFunctionType = FcnGetAndCheckSFunctionType(block)
 
  %switch sFunctionType
       
  %case "TLC"
    %if SLibIsMainCodeGenPhase()
      %assign origModuleIdx = ::CurrentModuleIdx
      %assign ::CurrentModuleIdx = system.CGIRModuleIdx
      %<GENERATE_TYPE(block, "BlockTypeSetup", funcName, system)>
      %assign ::CurrentModuleIdx = origModuleIdx
    %else
      %<GENERATE_TYPE(block, "BlockTypeSetup", funcName, system)>
    %endif
    %break
 
  %case "C-MEX"
 
    %% Model interface requires that all S-Functions are inlined
 
    %assign raccelUseMexFile = ...
      ::isRAccel && ParamSettings.WillBeDynamicallyLoaded == "yes"
     
    %if LibSFunctionLevel() == "RTWLevel2" && !raccelUseMexFile
      %assign sfcnInc1 = "%<funcName>cn_rtw/%<funcName>.h"
      %assign sfcnInc2 = "%<funcName>cn_rtw/%<funcName>_private.h"
 
      %openfile tmpBuf1
      #if !defined(RTW_GNERATED_SFCN_NOT_PRIVATE_%<funcName>)
        #define RTW_GNERATED_SFCN_NOT_PRIVATE_%<funcName>
      #endif
      %closefile tmpBuf1
      %openfile tmpBuf2
      #if !defined(MATLAB_MEX_FILE)
      #undef S_FUNCTION_NAME
      #include "%<sfcnInc1>"
      #include "%<sfcnInc2>"
      #endif
      %closefile tmpBuf2
 
      %openfile tmpBuf
      %<tmpBuf1>
      %<tmpBuf2>
      %closefile tmpBuf
       
      %<LibCacheIncludes(tmpBuf)>/
      %<SLibCacheCodeToFile("mdl_data_typedef", tmpBuf2)>
    %endif
 
  %endswitch
%endfunction %% BlockTypeSetup
 
 
%%Function:BlockInitialValues================================================
%%Abstract:
%%Returnappropriateinitializer"strings"forthevariousvectortypes.
%%
%function BlockInitialValues(block, system, vectType) void
 
  %assign ans = ""
 
  %assign funcName = ParamSettings.FunctionName
  %if SFunctionType == "TLC"
 
    %assign ans = GENERATE_TYPE(block, "BlockInitialValues", ...
      funcName, system, vectType)
 
  %endif
  %return ans
 
%endfunction %% BlockInitialValues
 
%%Function:SfunctionSampleHitGuard===========================================
%%Abstract:
%%Guardforsamplehits
%%
%function SfunctionSampleHitGuard()
  %assign sampleHitGuard = ""
  %assign orOperator = ""
  %assign noGuardNeeded = TLC_FALSE
  %assign multTIDs = TLC_FALSE
  
  %if LibTriggeredTID(TID) || ISEQUAL(TID, "constant") || ...
    LibAsynchronousTriggeredTID(TID) || ...
    SLibIsPeriodicRateGrouping() || SIZE(TID,1) == 1
    %assign noGuardNeeded = TLC_TRUE
  %else
    %assert(TYPE(TID) == "Vector")
    %foreach idx = SIZE(ParamSettings.SampleTimesToSet, 0)
      %% This is the model sample time index
      %assign tidIdx = ParamSettings.SampleTimesToSet[idx][1]
      %if tidIdx == -2 %% ContantTid
    %continue
      %endif
      %if SLibModelWideEventTID(tidIdx)
        %continue
      %endif
      %assign tidString = LibIsSampleHit(tidIdx)
      %if tidString == "1"
    %assign noGuardNeeded = TLC_TRUE
      %endif
      %assign multTIDs = !ISEMPTY(sampleHitGuard)
      %assign sampleHitGuard = sampleHitGuard + "%<orOperator>%<tidString>"
      %assign orOperator = " || "
    %endforeach
     
    %% Check if we really have multiple TIDs
    %if !multTIDs
      %assign noGuardNeeded = TLC_TRUE
    %endif
  %endif
  %return (noGuardNeeded) ? "" : sampleHitGuard
%endfunction %% SfuntionSampleHitGuard
 
 
 
%%Function:BlockInstanceData================================================
%%Abstract:
%%PerformS-functionBlockInstanceDatafunction
%%
%function BlockInstanceData(block, system) Output
  %switch SFunctionType
    %case "TLC"
      %assign funcName = ParamSettings.FunctionName
 
      %<GENERATE_TYPE(block, "BlockInstanceData", funcName, system)>/
 
      %break
  %endswitch
%endfunction
 
 
%%Function:BlockOutputSignal=================================================
%%Abstract:
%%PerformS-functionBlockOutputSignalfunction
%%
%function BlockOutputSignal(block,system,portIdx,ucv,lcv,sigIdx,retType) void
  %switch SFunctionType
    %case "TLC"
      %assign funcName = ParamSettings.FunctionName
 
      %return GENERATE_TYPE(block, "BlockOutputSignal", funcName, ...
    system,portIdx,ucv,lcv,sigIdx,retType)
 
      %%break
  %endswitch
%endfunction
 
%%
%%PerformS-functionSetupRuntimeResourcesfunction
%%oOnlyLevel2C-MEXS-FunctionshavemdlSetupRuntimeResources
%%
%function SetupRuntimeResources(block, system) Output
  %%
  %switch SFunctionType
    %case "TLC"
      %assign funcName = ParamSettings.FunctionName
 
      %<GENERATE_TYPE(block, "SetupRuntimeResources", funcName, system)>
 
      %break
    %case "C-MEX"
      %if ParamSettings.FunctionLevel == 2 && !ParamSettings.SetupRuntimeResourcesEmpty
        %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
        %assign s = ::tChildSimStruct
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
          %assign methodName = "sfcnSetupRuntimeResources"
           
          %if ::isRAccel || IsModelReferenceSimTarget()
            %assign actualFcnCall = ...
              "ssGetmdlSetupRuntimeResources(%<s>)"
            %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
              s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
            %<raccelCall>
          %else
            %assign methodCall = methodName + "(" + s + ");"
            %<methodCall>
          %endif
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
        }
 
      %endif
  %endswitch
%endfunction
 
 
%%Function:Start============================================================
%%Abstract:
%%PerformS-functionStartfunction
%%oOnlyLevel2C-MEXS-FunctionshavemdlStart
%%
%function Start(block, system) Output
  %%
  %switch SFunctionType
    %case "TLC"
      %assign funcName = ParamSettings.FunctionName
 
      %<GENERATE_TYPE(block, "Start", funcName, system)>
 
      %break
    %case "C-MEX"
      %if ParamSettings.FunctionLevel == 2 && !ParamSettings.StartEmpty
        %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
        %assign s = ::tChildSimStruct
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
          %assign methodName = "sfcnStart"
           
          %if ::isRAccel || IsModelReferenceSimTarget()
            %assign actualFcnCall = ...
              "ssGetmdlStart(%<s>)"
            %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
              s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
            %<raccelCall>
          %else
            %assign methodCall = methodName + "(" + s + ");"
            %<methodCall>
          %endif
           
      if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
    }
 
      %endif
  %endswitch
%endfunction
 
 
%%Function:InitializeConditions=============================================
%%Abstract:
%%1)PerformS-functionInitializeConditionsfunction
%%2)RegistertheS-functionintheregistrationtable.
%%
%function InitializeConditions(block, system) Output
  %switch SFunctionType
    %case "OTHER"
      %% This is a MEX-version s-function, run it for the Accelerator
      %if ::Accelerator
        %if !ParamSettings.InitializeConditionsEmpty
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
          /* Call into Simulink for MEX-version of S-function */
          %<SLibCallBlockInSimulink(system, block, ...
            "SS_CALL_MDL_INITIALIZE_CONDITIONS")>
 
        %endif
      %endif
      %break
    %case "TLC"
      %assign funcName = ParamSettings.FunctionName
 
      %<GENERATE_TYPE(block, "InitializeConditions", funcName, system)>
 
      %break
    %case "C-MEX"
      %if !ParamSettings.InitializeConditionsEmpty
        %if ::Accelerator
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
          /* Call into Simulink for MEX-version of S-function */
          %<SLibCallBlockInSimulink(system, block, ...
            "SS_CALL_MDL_INITIALIZE_CONDITIONS")>
 
        %else
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign s = ::tChildSimStruct
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
          {
            SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
            %switch ParamSettings.FunctionLevel
              %case 1
                %%
                %% Level 1
                %%
                real_T *sfcnX = ssGetContStates(%<s>);
                sfcnInitializeConditionsLevel1(sfcnX, %<s>);
        if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
        %%
                %% need to check if the s-function has mixed continuous/discrete states.
                %% if so, and, they are not the only states in the system, then we must
                %% account for the fact that the continuous and discrete states are not
                %% contiguous in the model's state vector, and copy them back into the
                %% global state vector.
                %%
                %assign numContStates = ContStates[0]
                %assign numDiscStates = DiscStates[0]
                %assign numBlkStates = numContStates + numDiscStates
                %if numContStates > 0 && numDiscStates > 0
                  %assign Xc = "&%<LibBlockContinuousState("", "", 0)>"
                  %assign Xd = "&%<LibBlockDiscreteState("", "", 0)>"
                  %<FcnCopyStatesFromWorkVector(s, Xc, Xd)>/
                %endif
                %break
 
              %case 2
                %%
                %% Level 2
                %%
 
                %assign methodName = "sfcnInitializeConditions"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    s + "->modelMethods.sFcn.mdlInitializeConditions.level2"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName,"", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
        if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
        %break
            %endswitch
          }
        %endif
      %endif
      %break
  %endswitch
%endfunction %% InitializeConditions
 
 
%%FunctionFcnGetTIDForSfcn=====================
%%Abstract:
%%Hard-codetheTIDifsubsystemisrategrouping
%%becauserategroupingcodemaynotpasstheTID
%%
%%Hard-codetheTIDforsingle-rates-functions
%%ThisisnecessarybecauseERTmaynotpasstheTIDto
%%theoutputfunctionforsingle-ratesystems
%%
%%Note:ifTID=[01]andTID01EQ,needhard-codetheTID
%%too.Systemthathastid[01]istreatedassinglrate
%%subsystem.ERTmaynotpassthetidtooutputfunction.
%%
%function FcnGetTIDForSfcn(block, system)
  %assign tid = block.TID
 
  %if ISEQUAL(tid, "constant")
    %assign tid = 0
  %elseif SLibIsMultiRateAndPeriodicRateGrouping(system)
    %assign tid = system.CurrentTID
  %elseif SLibIsERTCodeFormat()
    %if TYPE(tid) == "Vector"
      %assign isZeroTid = TLC_FALSE
      %if ISEQUAL(SolverType, "FixedStep") && FixedStepOpts.TID01EQ
        %assign isZeroTid = TLC_TRUE
        %foreach idx = SIZE(tid,1)
          %if !ISEQUAL(tid[idx], 0) && ...
            !ISEQUAL(tid[idx], 1)
            %assign isZeroTid = TLC_FALSE
            %break
          %endif
        %endforeach
      %endif
      %assign tid = isZeroTid ? 0 : LibTID()
    %else
      %assign tid = SLibGetNumericTID(block)
    %endif
  %else
    %assign tid = LibTID()
  %endif
 
  %if IsModelReferenceTarget()
    %assign tidMap = FcnGetMdlRefGlobalTIDMap("")
    %assign indx = "%<tidMap>[%<tid>]"
    %return indx
  %else
    %return tid
  %endif
%endfunction
 
%%Function:Update===========================================================
%%Abstract:
%%PerformS-functionUpdatefunction
%%
%function Update(block, system) Output
  %switch SFunctionType
    %case "OTHER"
      %% This is a MEX-version s-function, run it for the Accelerator
      %if ::Accelerator
        %if !ParamSettings.UpdateEmpty
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
          /* Call into Simulink for MEX-version of S-function */
          %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_UPDATE")>
 
        %endif
      %endif
      %break
    %case "TLC"
      %assign funcName = ParamSettings.FunctionName
 
      %<GENERATE_TYPE(block, "Update", funcName, system)>
 
      %break
    %case "C-MEX"
      %if ::Accelerator
        %if !ParamSettings.UpdateEmpty
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
          /* Call into Simulink for MEX-version of S-function */
          %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_UPDATE")>
 
        %endif
      %else
        %%
        %% A call to sfcnUpdate(...) is only generated when the number of
        %% discrete states in the s-function is greater than zero or the
        %% S-function is not direct feedthrough.
        %%
        %assign numDiscStates = DiscStates[0]
        %if ParamSettings.FunctionLevel == 1
          %assign directFeedthrough = ParamSettings.DirectFeedthrough
        %else
          %assign directFeedthrough = "no"
          %foreach ipIdx = NumDataInputPorts
            %if ParamSettings.DirectFeedthrough[ipIdx] == "yes"
              %assign directFeedthrough = "yes"
              %break
            %endif
          %endforeach
        %endif
        %%
        %% The rules for calling the S-function's update function
        %%
        %% Level 1: NumDiscStates > 0 || DirectFeedThrough
        %% Level 2: UpdateNotEmpty
        %%
        %% Note that UpdateNotEmpty means MDL_UPDATE was defined
        %%
        %assign callUpdate = 0
        %assign ps = ParamSettings
        %if ps.FunctionLevel == 1
          %% level 1
          %if numDiscStates > 0 || directFeedthrough == "no"
            %assign callUpdate = 1
          %endif
        %elseif ps.FunctionLevel == 2
          %% level 2
          %if !ps.UpdateEmpty
            %assign callUpdate = 1
          %endif
        %endif
        %if callUpdate
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
          {
            %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
            %assign s = ::tChildSimStruct
            %assign tid = FcnGetTIDForSfcn(block,system)
            SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
            %switch ps.FunctionLevel
              %case 1
                %%
                %% Level 1
                %%
                %if CodeFormat == "S-Function"
                  real_T *sfcnU = _ssGetU(%<s>);
                %else
                  real_T *sfcnU = ssGetU(%<s>);
                %endif
                real_T *sfcnX = ssGetContStates(%<s>);
                sfcnUpdateLevel1(sfcnX, sfcnU, %<s>, %<tid>);
        if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
 
        %%
                %% Need to check if the s-function has mixed continuous/
                %% discrete states. If so, and, they are not the only states
                %% in the system, then we must account for the fact that the
                %% continuous and discrete states are not contiguous in the
                %% model's state vector.
                %%
                %assign numContStates = ContStates[0]
                %assign numBlkStates = numContStates + numDiscStates
                %if numContStates > 0 && numDiscStates > 0
                  %assign Xc = "&%<LibBlockContinuousState("", "", 0)>"
                  %assign Xd = "&%<LibBlockDiscreteState("", "", 0)>"
                  %<FcnCopyStatesFromWorkVector(s, Xc, Xd)>/
                %endif
                %break
 
              %case 2
                %%
                %% Level 2
                %%
                %assign stGuard = SfunctionSampleHitGuard()
                %assign needGuard = (stGuard != "") && (IsModelReferenceSimTarget() || ::isRAccel || ::Accelerator)
                %if needGuard
                  if (%<stGuard>) {
                %endif
 
                %assign methodName = "sfcnUpdate"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    "ssGetmdlUpdate(%<s>)"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, tid, actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + "," + STRING(tid) + ");"
                  %<methodCall>
                %endif
                 
                %if needGuard
                 }
                %endif
                 
        if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
        %break
            %endswitch
          }
 
        %endif
      %endif
      %break
  %endswitch
%endfunction %% Update
 
 
%%Function:Derivatives======================================================
%%Abstract:
%%PerformS-functionDerivativesfunction
%%
%function Derivatives(block, system) Output
  %if CodeFormat == "S-Function" || IsModelReferenceTarget()
    %assign underScore = "_"
  %else
    %assign underScore = ""
  %endif
  %%
  %% a call to sfcnDerivatives(...) is only generated when the number of
  %% continuous states in the s-function is greater than zero or it calls
  %% the continuous action state
  %%
  %assign numContStates = ContStates[0]
  %%
  %switch SFunctionType
  %case "OTHER"
    %% This is a MEX-version s-function, run it for the Accelerator
    %if ::Accelerator
      %if numContStates > 0 && !ParamSettings.DerivativesEmpty
    /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
    /* Call into Simulink for MEX-version of S-function */
    %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_DERIVATIVES")>
      %endif
    %endif
    %break
  %case "TLC"
    %assign funcName = ParamSettings.FunctionName
 
    %<GENERATE_TYPE(block, "Derivatives", funcName, system)>
 
    %break
  %case "C-MEX"
    %if (numContStates > 0 && !ParamSettings.DerivativesEmpty) || (ParamSettings.CallSimulinkStateWithContStates == "yes")
      %if ::Accelerator
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        /* Call into Simulink for MEX-version of S-function */
        %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_DERIVATIVES")>
 
      %else
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign s = ::tChildSimStruct
          %assign optStartIndex = SLibGet1DArrayIndexer(numContStates,"","",0)
          SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
      %if IsModelReferenceTarget()
            real_T *sfcndX_fx = (real_T *) ...
              &%<LibBlockContinuousStateDerivative("", "", 0)>;
          %else
              %% caller used semantic sugar "with the block"
              %assign cs = ::CompiledModel.ContStates.ContState[ContStates[1]]
              real_T *sfcndX_fx = (real_T *) &((%<::tXdotType> *) ...
                %<RTMGet("dX")>)->%<cs.Identifier>%<optStartIndex>;
          %endif
          %switch ParamSettings.FunctionLevel
            %case 1
              %%
              %% Level 1
              %%
              real_T *sfcnU = %<underScore>ssGetU(%<s>);
              real_T *sfcnX = ssGetContStates(%<s>);
              %%
              %% Note that Simulink 1.3 copies the non-contiguous states into
              %% the work vector, however this is not required.
              %%
              %<underScore>ssSetdX(%<s>, sfcndX_fx);
              sfcnDerivativesLevel1(sfcndX_fx, sfcnX, sfcnU, %<s>, 0);
              if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
          %break
 
            %case 2
              %%
              %% Level 2
              %%
              %<underScore>ssSetdX(%<s>, sfcndX_fx);
 
                %assign methodName = "sfcnDerivatives"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    "ssGetmdlDerivatives(%<s>)"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
          %break
          %endswitch
        }
 
      %endif
    %endif
    %break
  %endswitch
%endfunction %% Derivatives
 
 
%%Function:Projection======================================================
%%Abstract:
%%PerformS-functionProjectionfunction
%%
%function Projection(block, system) Output
  %%
  %% a call to sfcnProjection(...) is only generated when the number of
  %% continuous states in the s-function is greater than zero.
  %%
  %assign numContStates = ContStates[0]
  %%
  %switch SFunctionType
  %case "OTHER"
    %% This is a MEX-version s-function, run it for the Accelerator
    %if ::Accelerator
      %if numContStates > 0 && !ParamSettings.ProjectionEmpty
    /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
    /* Call into Simulink for MEX-version of S-function */
    %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_PROJECTION")>
      %endif
    %endif
    %break
  %case "TLC"
    %if ParamSettings.HasMdlProjection == "yes"
      %assign funcName = ParamSettings.FunctionName
      %<GENERATE_TYPE(block, "Projection", funcName, system)>
    %endif
    %break
  %case "C-MEX"
    %if numContStates > 0 && !ParamSettings.ProjectionEmpty || (ParamSettings.CallSimulinkStateWithContStates == "yes")
      %if ::Accelerator
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        /* Call into Simulink for MEX-version of S-function */
        %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_PROJECTION")>
 
      %else
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign s = ::tChildSimStruct
          %assign optStartIndex = SLibGet1DArrayIndexer(numContStates,"","",0)
          %switch ParamSettings.FunctionLevel
            %case 2
              %%
              %% Level 2
              %%
              SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
 
                %assign methodName = "sfcnProjection"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    "ssGetmdlProjection(%<s>)"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
          %break
          %endswitch
        }
 
      %endif
    %endif
    %break
  %endswitch
%endfunction %% Projection
 
 
%%Function:ForcingFunction======================================================
%%Abstract:
%%PerformS-functionForcingFunctionfunction
%%
%function ForcingFunction(block, system) Output
   
  %if ParamSettings.IsLinearlyImplicit == "no"
    %% Call Derivatives for explicit pieces of linearly-implicit systems.
    %<Derivatives(block,system)>
    %return
  %endif
         
  %if CodeFormat == "S-Function" || IsModelReferenceTarget()
    %assign underScore = "_"
  %else
    %assign underScore = ""
  %endif
  %%
  %% a call to sfcnForcingFunction(...) is only generated when the number of
  %% continuous states in the s-function is greater than zero.
  %%
  %assign numContStates = ContStates[0]
  %%
  %switch SFunctionType
  %case "OTHER"
    %% This is a MEX-version s-function, run it for the Accelerator
    %if ::Accelerator
      %if numContStates > 0 && !ParamSettings.ForcingFunctionEmpty
    /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
    /* Call into Simulink for MEX-version of S-function */
    %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_FORCINGFUNCTION")>
      %endif
    %endif
    %break
  %case "TLC"
    %if ParamSettings.IsLinearlyImplicit == "yes"
      %assign funcName = ParamSettings.FunctionName
 
      %<GENERATE_TYPE(block, "ForcingFunction", funcName, system)>
    %endif
    %break
  %case "C-MEX"
    %if numContStates > 0 && !ParamSettings.ForcingFunctionEmpty || (ParamSettings.CallSimulinkStateWithContStates == "yes")
      %if ::Accelerator
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        /* Call into Simulink for MEX-version of S-function */
        %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_FORCINGFUNCTION")>
 
      %else
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign s = ::tChildSimStruct
          %assign optStartIndex = SLibGet1DArrayIndexer(numContStates,"","",0)
          SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
      %if IsModelReferenceTarget()
            real_T *sfcndX_fx = (real_T *) ...
              &%<LibBlockContinuousStateDerivative("", "", 0)>;
          %else
              %% caller used semantic sugar "with the block"
              %assign cs = ::CompiledModel.ContStates.ContState[ContStates[1]]
              real_T *sfcndX_fx = (real_T *) &((%<::tXdotType> *) ...
                %<RTMGet("dX")>)->%<cs.Identifier>%<optStartIndex>;
          %endif
          %switch ParamSettings.FunctionLevel
            %case 2
              %%
              %% Level 2
              %%
              %<underScore>ssSetdX(%<s>, sfcndX_fx);
 
                %assign methodName = "sfcnForcingFunction"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    "ssGetmdlForcingFunction(%<s>)"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
          %break
          %endswitch
        }
 
      %endif
    %endif
    %break
  %endswitch
%endfunction %% ForcingFunction
 
 
%%Function:MassMatrix======================================================
%%Abstract:
%%PerformS-functionMassMatrixfunction
%%
%function MassMatrix(block, system) Output
  %%
  %% a call to sfcnMassMatrix(...) is only generated when the number of
  %% continuous states in the s-function is greater than zero.
  %%
  %assign numContStates = ContStates[0]
  %%
  %switch SFunctionType
  %case "OTHER"
    %% This is a MEX-version s-function, run it for the Accelerator
    %if ::Accelerator
      %if numContStates > 0 && !ParamSettings.MassMatrixEmpty
    /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
    /* Call into Simulink for MEX-version of S-function */
    %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_MASSMATRIX")>
      %endif
    %endif
    %break
  %case "TLC"
    %if ParamSettings.IsLinearlyImplicit == "yes"
      %assign funcName = ParamSettings.FunctionName
      %if SLibPartitionGroupingSystem(system)
        %assign savedPID = ::GlobalCurrentPID
        %% tid of continuous rate is always 0
        %assign ::GlobalCurrentPID = SLibGetPIDFromBlock(block, 0 /% tid %/)
      %endif
      %<GENERATE_TYPE(block, "MassMatrix", funcName, system)>
      %if SLibPartitionGroupingSystem(system)
        %assign ::GlobalCurrentPID = savedPID
      %endif
    %endif
    %break
  %case "C-MEX"
    %if numContStates > 0 && !ParamSettings.MassMatrixEmpty || (ParamSettings.CallSimulinkStateWithContStates == "yes")
      %if ::Accelerator
        %assert ParamSettings.Inlined != "yes"
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        /* Call into Simulink for MEX-version of S-function */
        %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_MASSMATRIX")>
 
      %else
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign s = ::tChildSimStruct
          SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
          %switch ParamSettings.FunctionLevel
            %case 2
              %%
              %% Level 2
              %%
              %% set MassMatrixPr on local SimStructs
              ssSetMassMatrixPr(%<s>,%<SLibBlockMassMatrixPr()>);
 
                %assign methodName = "sfcnMassMatrix"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    "ssGetmdlMassMatrix(%<s>)"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
          %break
          %endswitch
        }
 
      %endif
    %endif
    %break
  %endswitch
%endfunction %% MassMatrix
 
%%Function:InvokeFcnCallForTracking==========================================
%%Abstract:
%%Invokesfunctioncallsinordertoenabletrackingofgloballyaccessed
%%argumentsincasetheFNIsubsystemislocatedinareusedsystem.
%%
%function InvokeFcnCallForTracking(sfcnBlock, callType) void
  %foreach callIdx = sfcnBlock.NumSFcnSysOutputCallDsts
    %with sfcnBlock.SFcnSystemOutputCall[callIdx]
      %% skip unconnected function call outputs
      %if ISEQUAL(BlockToCall, "unconnected")
        %continue
      %endif
      %assign sysIdx = BlockToCall[0]
      %assign blkIdx = BlockToCall[1]
      %assign ssBlock = ::CompiledModel.System[sysIdx].Block[blkIdx]
      %assign isSubsystem = (ssBlock.Type == "SubSystem")
      %if isSubsystem
        %assign dstSysIdx = ssBlock.SubsystemParamSettings.SystemIdx
        %if !FcnSubsystemIsAsycnTopSS(::CompiledModel.System[dstSysIdx])
          %% call the downstream system
          %assign unused = ...
            LibExecuteFcn%<callType>(ssBlock, FcnPortElement, ...
            ParamSettings.SampleTimesToSet[0][1])
        %endif
      %endif
    %endwith
  %endforeach
%endfunction
 
%%Function:InvokeOutputsFcnCallForTracking===================================
%%Abstract:
%%Invokesfunctioncallsinordertoenabletrackingofgloballyaccessed
%%argumentsincasetheFNIsubsystemislocatedinareusedsystem.
%%
%function InvokeOutputsFcnCallForTracking(sfcnBlock) void
  %<InvokeFcnCallForTracking(sfcnBlock, "Call")>
  %if sfcnBlock.ParamSettings.ExplicitFCSSCtrl == "yes"
    %<InvokeFcnCallForTracking(sfcnBlock, "Enable")>
    %<InvokeFcnCallForTracking(sfcnBlock, "Disable")>
  %endif
%endfunction
 
%%Function:Outputs==========================================================
%%Abstract:
%%PerformS-functionOutputsfunction
%%
%function Outputs(block, system) void
  %openfile tmpBuf
  %%
  %switch SFunctionType
    %case "OTHER"
      %% This is a MEX-version s-function, run it for the Accelerator
      %if ::Accelerator
        %if !ParamSettings.OutputsEmpty
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
          /* Call into Simulink for MEX-version of S-function */
          %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_OUTPUTS")>
          %<InvokeOutputsFcnCallForTracking(block)>
        %endif
      %endif
      %break
    %case "TLC"
      %% We must generate code of a subsystem associated with an
      %% asynchronous rate after code generation of other blocks is done.
      %% When a block calls a async system, a new field "GenCodeForTopAsyncSS"
      %% is added to the block. This field will be use later to generate async
      %% system code after code generation of other blocks is done.
      %%
      %% We generate code for this block only if
      %% 1. This block does not call an async system
      %% 2. This block calls an async system and the block itself
      %% generates code
      %% 3. Flag GenCodeForTopAsyncSS is TLC_TRUE
      %%
      %if !ISFIELD(block, "GenCodeForTopAsyncSS") && ...
    ISFIELD(block, "NumSFcnSysOutputCallDsts")
    %foreach callIdx = NumSFcnSysOutputCallDsts
      %% Get downstream block if there is one
      %if "%" == "unconnected"
        %continue
      %endif
          %if FcnBlkIsAsyncTopSfcn(block)
            %addtorecord block GenCodeForTopAsyncSS TLC_FALSE
            %break
          %endif
    %endforeach
      %endif
      %%
      %assign genCode = TLC_FALSE
      %if !ISFIELD(block, "GenCodeForTopAsyncSS")
    %% not a TopAsyncSS caller, always generate code
    %assign genCode = TLC_TRUE
      %elseif ISFIELD(block, "AsyncCallerGenCode") && ...
        AsyncCallerGenCode == TLC_TRUE
        %% Async system caller itself generates code
        %assign genCode = TLC_TRUE
      %elseif block.GenCodeForTopAsyncSS
    %% generate TopAsyncSS code when GenCodeForTopAsyncSS
    %% is set to true
    %assign genCode = TLC_TRUE
      %endif
      %%
      %if genCode
        %assign funcName = ParamSettings.FunctionName
        %%
        %<GENERATE_TYPE(block, "Outputs", funcName, system)> /
 
      %endif
      %%
      %break
    %case "C-MEX"
      %%
      %with block
    %if SLibIsERTCodeFormat() && !IsModelReferenceSimTarget()
          %assert TYPE(TID) == "Vector" || ...
            TYPE(TID) == "Number" || ...
            ISEQUAL(TID, "triggered") || ...
            ISEQUAL(TID, "constant")
          
      %if TYPE(TID) == "Vector"
            %if !FcnBlkIsAsyncTopSfcn(block)
              %assign numTids = SIZE(TID,1)
              %assign ::CompiledModel.RequireMultiRateSampleHits = (numTids > 1)
              %foreach i = numTids
                %assign tid = TID[i]
                %foreach j = numTids - i - 1
                  %% If is multirate sfunction no-inline sfunction,
                  %% assume RequireMultiRateSampleHit between all
                  %% of it tids.
                  %assign sti = TID[j+i+1]
                  %% Need update special sample hit flag for
                  %% noninlned multirate sfcn
                  %<SLibSetNeedRateInteraction(sti,tid)>
                %endforeach
                %% assume each tid of the sfunc need absolute time
                %% and NeedFloatTime
                %%
                %<SLibSetNeedFloatAbsoluteTime(tid)>
              %endforeach
            %endif
      %elseif TYPE(TID) == "Number"
            %<SLibSetNeedFloatAbsoluteTime(TID)>
      %elseif ISEQUAL(TID, "triggered")
        %assert TYPE(TriggerTID) == "Vector" && TriggerTID[0] >= 0
            %<SLibSetNeedFloatAbsoluteTime(TriggerTID[0])>
      %endif
    %endif
      %endwith
      %if !ParamSettings.OutputsEmpty
        %<InvokeOutputsFcnCallForTracking(block)>
        %if ::Accelerator
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
          /* Call into Simulink for MEX-version of S-function */
          %<SLibCallBlockInSimulink(system, block, "SS_CALL_MDL_OUTPUTS")>
 
        %else
          /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
      %if ISFIELD(block, "SampleTimeIdx") && ...
        !ISEQUAL(SampleTimeIdx, TID)
        %% this is a Rate-Transition non-inlined sfunction
        %% it output code must guarded by IsSpecialSampleHit
        %assert TYPE(TID) == "Number" && TYPE(SampleTimeIdx) == "Number"
        if( %<LibIsSpecialSampleHit(SampleTimeIdx, TID)> ) {
      %else
        {
      %endif
            %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
            %assign s = ::tChildSimStruct
            %assign tid = FcnGetTIDForSfcn(block,system)
            SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
        %switch ParamSettings.FunctionLevel
              %case 1
                %%
                %% Level 1
                %%
                %if CodeFormat == "S-Function"
                  real_T *sfcnU = _ssGetU(%<s>);
                %else
                  real_T *sfcnU = ssGetU(%<s>);
                %endif
                real_T *sfcnX = ssGetContStates(%<s>);
                %%
                %assign sfcnY = SLibGetNullDefinitionFromTfl()
                %if NumDataOutputPorts > 0
          %assign idnum = IDNUM(DataOutputPort[0].SignalSrc[0])
                  %if idnum[0] != "F" %%FcnCall
                    %assign sfcnY = "sfcnY"
                    real_T *sfcnY = &(%<LibBlockOutputSignal(0,"","",0)>);
                  %endif
                %endif
                %%
                %% need to check if the s-function has mixed continuous/
        %% discrete states. if so, and, they are not the only states in
        %% the system, then we must account for the fact that the
        %% continuous and discrete states are not contiguous in the
        %% model's state vector.
                %%
                %assign numContStates = ContStates[0]
                %assign numDiscStates = DiscStates[0]
                %assign numBlkStates = numContStates + numDiscStates
                %if numContStates > 0 && numDiscStates > 0
                  %assign Xc = "&%<LibBlockContinuousState("", "", 0)>"
                  %assign Xd = "&%<LibBlockDiscreteState("", "", 0)>"
          (void) %<LibGenMemFcnCall("memcpy", "sfcnX", Xc, ...
            "ssGetNumContStates(%<s>)*sizeof(real_T)")>;
          if (ssIsMajorTimeStep(%<s>) ) {
          (void) %<LibGenMemFcnCall("memcpy", ...
            "sfcnX+ssGetNumContStates(%<s>)", Xd, ...
            "ssGetNumDiscStates(%<s>)*sizeof(real_T)")>;
                  }
                  sfcnOutputsLevel1(%<sfcnY>, sfcnX, sfcnU, %<s>, %<tid>);
          %if CodeFormat == "S-Function" || IsModelReferenceTarget()
            if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
          %endif
          if( ssIsMajorTimeStep(%<s>) ) {
            %<FcnCopyStatesFromWorkVector(s, Xc, Xd)>/
          }
        %else
          sfcnOutputsLevel1(%<sfcnY>, sfcnX, sfcnU, %<s>, %<tid>);
          %if CodeFormat == "S-Function" || IsModelReferenceTarget()
            if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
          %endif
        %endif
                %break
 
              %case 2
                %%
                %% Level 2
                %%
        %if ParamSettings.HasVariableSampleTime == "yes"
                  real_T tNext;
                  if( %<LibIsSampleHit(block.VarTsTID)> ) {
                    if (ssGetTNextWasAdjusted(%<s>, %<block.VarTsTID>)) {
                    ssSetTNext(%<s>, ssGetT(%<s>));
                  }
                   
                %assign methodName = "sfcnGetTimeOfNextVarHit"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    s + "->modelMethods.sFcn.mdlGetTimeOfNextVarHit"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
                  tNext = ssGetTNext(%<s>);
                  %<LibSetVarNextHitTime(block,"tNext")>;
                }
              %endif
        %%
                %foreach opIdx = NumDataOutputPorts
                  %if !LibBlockOutputSignalIsInBlockIO(opIdx)
            %assign idnum = IDNUM(DataOutputPort[0].SignalSrc[0])
            %if idnum[0] != "F" %%FcnCall
              %assign yAddr = LibBlockOutputSignalAddr(opIdx, "", "", 0)
                      %if CodeFormat == "S-Function" || IsModelReferenceTarget()
                        _ssSetOutputPortSignal(%<s>, %<opIdx>, %<yAddr>);
                      %else
                        ssSetOutputPortSignal(%<s>, %<opIdx>, %<yAddr>);
                      %endif
                    %endif
                  %endif
        %endforeach
                %% Generate the ST guard if necessary
                %assign stGuard = SfunctionSampleHitGuard()
                %assign needGuard = (stGuard != "") && (IsModelReferenceSimTarget() || ::isRAccel || ::Accelerator)
                %if needGuard
                  if (%<stGuard>) {
                %endif
 
                %assign methodName = "sfcnOutputs"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    s + "->modelMethods.sFcn.mdlOutputs.level2"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, tid, actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + "," + STRING(tid) + ");"
                  %<methodCall>
                %endif
                 
                %if needGuard
                 }
                %endif
                 
        %if CodeFormat == "S-Function" || IsModelReferenceTarget()
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
        %endif
        %break
            %endswitch
          }
        %endif
      %endif
      %break
  %endswitch
  %closefile tmpBuf
  %return tmpBuf
%endfunction
 
 
%%Function:SetDims==========================================================
%%Abstract:
%%PerformS-functionSetDimsfunction
%%
%function SetDims(block, system, oIdx, rIdx) void
  %openfile tmpBuf
  %%
  %switch SFunctionType
    %case "TLC"
 
      %assign funcName = ParamSettings.FunctionName
      %%
      %<GENERATE_TYPE(block, "SetDims", funcName, system, oIdx, rIdx)> /
 
      %break
    %case "C-MEX"
      %if ::Accelerator
        %<SLibCallSFcnSetDimsInSimulink(system, block, oIdx, rIdx)>
      %endif
      %break
  %endswitch
  %closefile tmpBuf
  %return tmpBuf
%endfunction
 
 
%%Function:FinalizeAllDims==========================================================
%%Abstract:
%%PerformS-functionFinalizeAllDimsfunction
%%
%function FinalizeAllDims(block, system) void
  %openfile tmpBuf
  %%
  %switch SFunctionType
    %case "TLC"
 
      %assign funcName = ParamSettings.FunctionName
      %%
      %<GENERATE_TYPE(block, "FinalizeAllDims", funcName, system)> /
 
      %break
  %endswitch
  %closefile tmpBuf
  %return tmpBuf
%endfunction
 
 
%%Function:Enable============================================================
%%Abstract:
%%PerformS-functionEnableforgeneratedS-Functions
%%
%function Enable(block, system) Output
  %openfile buffer
  
  %switch SFunctionType
    %case "TLC"
      %if ParamSettings.HasVariableSampleTime == "yes"
        %<SLibResetNextVHTDueToEnable(block)>
      %endif
      %if LibSFunctionLevel() == "RTWLevel2"
        %if ParamSettings.FunctionLevel == 2 && !ParamSettings.EnableEmpty
          %<LibBlockReportError(block, "Inlined Enable function not supported.")>
        %endif
      %else
    %assign funcName = ParamSettings.FunctionName
        %if !ISFIELD(block, "GenCodeForTopAsyncSS") && ...
          FcnBlkIsAsyncTopSfcn(block) && ...
          (IsModelReferenceTarget() || SLibIsExportFcnDiagram())
          %addtorecord block GenCodeForTopAsyncSS TLC_FALSE
        %endif
    %<GENERATE_TYPE(block, "Enable", funcName, system)>
      %endif
      %break
    %case "C-MEX"
      %if ParamSettings.HasVariableSampleTime == "yes"
        %<SLibResetNextVHTDueToEnable(block)>
      %endif
      %if ::Accelerator
    /* Call into Simulink for MEX-version of S-function */
    %<SLibCallBlockInSimulink(system,block,"SS_CALL_RTW_GENERATED_ENABLE")>
      %else
    %if LibSFunctionLevel() == "RTWLevel2"
      %if ParamSettings.FunctionLevel == 2 && !ParamSettings.EnableEmpty
        %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
        %assign s = ::tChildSimStruct
        {
              SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
          sfcnRTWGeneratedEnable(%<s>);
        }
      %endif
    %else
      %if ParamSettings.FunctionLevel == 2 && !ParamSettings.EnableEmpty
        %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
        %assign s = ::tChildSimStruct
        {
              SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
 
              %assign methodName = "sfcnEnable"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    "ssGetmdlEnable(%<s>)"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
        }
      %endif
    %endif
      %endif
      %if ParamSettings.ExplicitFCSSCtrl == "yes"
        %<InvokeFcnCallForTracking(block, "Enable")>
      %endif
  %endswitch
  %closefile buffer
  %if !ISEMPTY(buffer) && !WHITE_SPACE(buffer)
    /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
    %<buffer>
 
  %endif
%endfunction %% Enable
 
 
%%Function:Disable===========================================================
%%Abstract:
%%PerformS-functionDisableforgeneratedS-Functions
%%
%function Disable(block, system) Output
  %openfile buffer
  %if ParamSettings.HasVariableSampleTime == "yes"
    %<LibSetVarNextHitTime(block,LibRealNonFinite("-inf"))>;
  %endif
  %switch SFunctionType
    %case "TLC"
      %if LibSFunctionLevel() == "RTWLevel2"
        %if ParamSettings.FunctionLevel == 2 && !ParamSettings.DisableEmpty
          %<LibBlockReportError(block, "Inlined Disable function not supported.")>
        %endif
      %else
    %assign funcName = ParamSettings.FunctionName
        %if !ISFIELD(block, "GenCodeForTopAsyncSS") && ...
          FcnBlkIsAsyncTopSfcn(block) && ...
          (IsModelReferenceTarget() || SLibIsExportFcnDiagram())
          %addtorecord block GenCodeForTopAsyncSS TLC_FALSE
        %endif
    %<GENERATE_TYPE(block, "Disable", funcName, system)>
      %endif
      %break
    %case "C-MEX"
      %if ::Accelerator
    /* Call into Simulink for MEX-version of S-function */
    %<SLibCallBlockInSimulink(system,block,"SS_CALL_RTW_GENERATED_DISABLE")>
      %else
    %if LibSFunctionLevel() == "RTWLevel2"
      %if ParamSettings.FunctionLevel == 2 && !ParamSettings.DisableEmpty
        %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
        %assign s = ::tChildSimStruct
        {
              SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
          sfcnRTWGeneratedDisable(%<s>);
        }
      %endif
    %else
      %if ParamSettings.FunctionLevel == 2 && !ParamSettings.DisableEmpty
        %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
        %assign s = ::tChildSimStruct
        {
              SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
 
                %assign methodName = "sfcnDisable"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    "ssGetmdlDisable(%<s>)"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
        }
      %endif
    %endif
      %endif
      %if ParamSettings.ExplicitFCSSCtrl == "yes"
        %<InvokeFcnCallForTracking(block, "Disable")>
      %endif
  %endswitch
  %closefile buffer
  %if !ISEMPTY(buffer) && !WHITE_SPACE(buffer)
    /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
    %<buffer>
 
  %endif
%endfunction %% Disable
 
 
%%Function:ZeroCrossings=====================================================
%%Abstract:
%%
%function ZeroCrossings(block, system) Output
  %if ParamSettings.FunctionLevel == 2
    %switch SFunctionType
      %case "TLC"
        %assign funcName = ParamSettings.FunctionName
 
    %<GENERATE_TYPE(block, "ZeroCrossings", funcName, system)>
 
    %break
      %case "C-MEX"
    %if ::Accelerator
      /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
      /* Call into Simulink for MEX-version of S-function */
      %<SLibCallBlockInSimulink(system,block,"SS_CALL_MDL_ZERO_CROSSINGS")>
    %else
      %if !ParamSettings.ZeroCrossingsEmpty
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign s = ::tChildSimStruct
              SimStruct *%<s> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
          ssSetNonsampledZCs(%<s>, &(%<LibBlockZCSignalValue("", "", 0, 0)>));
 
                %assign methodName = "sfcnZeroCrossings"
                %if ::isRAccel || IsModelReferenceSimTarget()
                  %assign actualFcnCall = ...
                    s + "->modelMethods.sFcn.mdlZeroCrossings"
                  %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
                    s, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
                  %<raccelCall>
                %else
                  %assign methodCall = methodName + "(" + s + ");"
                  %<methodCall>
                %endif
                 
          if(ssGetErrorStatus(%<s>) != %<SLibGetNullDefinitionFromTfl()>) return;
        }
      %endif
    %endif
 
        %break
    %endswitch
  %endif
%endfunction
 
 
%%Function:Terminate========================================================
%%Abstract:
%%PerformS-functionTerminatefunction
%%
%function Terminate(block, system) Output
  %switch SFunctionType
    %case "TLC"
      %assign funcName = ParamSettings.FunctionName
 
      %<GENERATE_TYPE(block, "Terminate", funcName, system)>
 
      %break
    %case "C-MEX"
      %if !ParamSettings.TerminateEmpty
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign simStruct = ::tChildSimStruct
          SimStruct *%<simStruct> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
 
          %assign methodName = "sfcnTerminate"
          %if ::isRAccel || IsModelReferenceSimTarget()
            %assign actualFcnCall = ...
                    simStruct + "->modelMethods.sFcn.mdlTerminate"
            %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
              simStruct, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
            %<raccelCall>
          %else
                  %assign methodCall = methodName + "(" + simStruct + ");"
                  %<methodCall>
          %endif
 
        }
      %endif
      %break
  %endswitch
%endfunction
 
%%Function:CleanupRuntimeResources========================================================
%%Abstract:
%%PerformS-functionCleanupRuntimeResourcesfunction
%%
%function CleanupRuntimeResources(block, system) Output
  %switch SFunctionType
    %case "TLC"
      %assign funcName = ParamSettings.FunctionName
      %<GENERATE_TYPE(block, "CleanupRuntimeResources", funcName, system)>
 
      %break
    %case "C-MEX"
      %if !ParamSettings.CleanupRuntimeResourcesEmpty
        /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
        {
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign simStruct = ::tChildSimStruct
          SimStruct *%<simStruct> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
 
          %assign methodName = "sfcnCleanupRuntimeResources"
          %if ::isRAccel || IsModelReferenceSimTarget()
            %assign actualFcnCall = ...
              simStruct + "->states.modelMethods2->modelMethods4->mdlCleanupRuntimeResources"
            %assign raccelCall = FcnGenerateCallForTargetThatCanUseSFcnMexFile(...
              simStruct, childSFunctionIdx, methodName, "", actualFcnCall, block.TLCBlockSID)
            %<raccelCall>
          %else
            %assign methodCall = methodName + "(" + simStruct + ");"
            %<methodCall>
          %endif
           
        }
      %endif
      %% param is protected by mexMakeArrayPersistent that means this memory will be protected
      %% between calls to the SimTarget function. We need to use mxDestroyArray
      %% to free the allocated memory
      %% We only cleanup memory for SimTarget (skip S-Function target)
      %assign numArgs = Parameters[0] / 2
      %if numArgs > 0
        %if IsModelReferenceSimTarget()
          %assign underScore = "_"
          %<SLibWriteSFunctionGuards("if")>
          %assign childSFunctionIdx = FcnChildSFunctionIndex(block)
          %assign simStruct = ::tChildSimStruct
          SimStruct *%<simStruct> = %<RTMGetIdxed("SFunction", childSFunctionIdx)>;
          %foreach argIdx = numArgs
            {
              mxArray *param = %<underScore>ssGetSFcnParam(%<simStruct>, %<argIdx>);
              if (!mxIsEmpty(param))
              {
                mxDestroyArray(param);
                %<underScore>ssSetSFcnParam(%<simStruct>, %<argIdx>, NULL);
              }
            }
          %endforeach
          %<SLibWriteSFunctionGuards("endif")>
        %endif
      %endif
      %break
  %endswitch
%endfunction
 
%%[EOF]gensfun.tlc