%implements TransportDelay "C"
%include "tdelay_sup.tlc"
%function BlockTypeSetup(block, system) void
%<TDelayTypeSetup(block, system)>
%endfunction
%function Start(block, system) Output
%assign isRSIM = isRSim
{
%assign blockWidth = LibBlockOutputSignalWidth(0)
%if !isRSIM
real_T *pBuffer = &%<LibBlockRWork(TUbufferArea, "", "", 0)>;
%endif
%assign localRollThreshold = 2
%assign useConstBufSzVect = 0
%if WILL_ROLL(RollRegions, localRollThreshold)
%if SIZE(ParamSettings.BufferSize,1) > 1
%<LibGenConstVectWithInit(ParamSettings.BufferSize,tSS_INT32,"bufSz")>
%assign useConstBufSzVect = 1
%endif
%endif
%assign rollVars = ["/Tail","/Head",...
"/Last","/CircularBufSize",...
"/TUbufferPtrs", "/InitialOutput"]
%roll idx = RollRegions, lcv = localRollThreshold, block, "Roller", rollVars
%if lcv == ""
%assign paramSettingIdx = idx
%else
%if idx == 0
%assign paramSettingIdx = lcv
%else
%assign paramSettingIdx = "%<lcv> + %<idx>"
%endif
%endif
%if useConstBufSzVect
%assign bufSz = "bufSz[%<paramSettingIdx>]"
%else
%assign bufSz = (SIZE(ParamSettings.BufferSize,1) == 1? ...
ParamSettings.BufferSize[0]: ...
ParamSettings.BufferSize[paramSettingIdx])
%endif
%assign tail = LibBlockIWork(Tail,"",lcv,idx)
%assign head = LibBlockIWork(Head,"",lcv,idx)
%assign last = LibBlockIWork(Last,"",lcv,idx)
%assign bufferSiz = LibBlockIWork(CircularBufSize,"",lcv,idx)
%assign initOutput= LibBlockParameter(InitialOutput, "",lcv,idx)
%if isRSIM
%if lcv == ""
{
%endif
%assign utilName = TDelay_CreateBuf(block)
real_T *pBuffer = (real_T *)%<utilName>(2, %<bufSz>, sizeof(real_T));
if (pBuffer == %<SLibGetNullDefinitionFromTfl()>) {
%<RTMSetErrStat("/"tdelay memory allocation error/"")>;
return;
}
%endif
%<tail> = 0;
%<head> = 0;
%<last> = 0;
%<bufferSiz> = %<bufSz>;
pBuffer[0] = %<initOutput>;
pBuffer[%<bufSz>] = %<LibGetT()>;
%if lcv != ""
%assign pUbuf = LibBlockPWork(TUbufferPtrs, "", lcv, idx)
%assign pTbuf = LibBlockPWork(TUbufferPtrs, "", ...
"%<lcv>+%<blockWidth>", idx)
%else
%assign pUbuf = LibBlockPWork(TUbufferPtrs, "", lcv, idx)
%assign pTbuf = LibBlockPWork(TUbufferPtrs, "", lcv, idx+blockWidth)
%endif
%<pUbuf> = (void *) &pBuffer[0];
%<pTbuf> = (void *) &pBuffer[%<bufSz>];
%if !isRSIM && ((lcv != "") || (lcv == "" && idx < blockWidth-1))
%if TYPE(bufSz) == "Number"
pBuffer += %<2*bufSz>;
%else
pBuffer += 2*%<bufSz>;
%endif
%endif
%if isRSIM && lcv == ""
}
%endif
%endroll
}
%endfunction
%function FcnIsReal(strValue)
%assign temp = FEVAL("sscanf",strValue,"%f%1s")
%return SIZE(temp,0) == 1
%endfunction
%function Outputs(block, system) Output
{
%assign blockWidth = LibBlockOutputSignalWidth(0)
%assign inport0Width = LibBlockInputSignalWidth(0)
%assign useConstIsDiscVect = 0
%assign localRollThreshold = 2
%assign tMinusDelayValue = ""
%if WILL_ROLL(RollRegions, localRollThreshold)
%if SIZE(ParamSettings.DiscreteInput,1) > 1
%<LibGenConstVectWithInit(ParamSettings.DiscreteInput,...
tSS_BOOLEAN,"isDiscrete")>
%assign useConstIsDiscVect = 1
%endif
%elseif blockWidth == 1
%assign delay = LibBlockParameter(DelayTime, "", "", 0)
%if FcnIsReal(delay)
%if %<delay> > 0.0
%assign tMinusDelayValue = "= simTime - %<delay>"
%else
%assign tMinusDelayValue = "= simTime"
%endif
%else
%assign tMinusDelayValue = "= simTime - %<delay>"
%endif
%endif
%assign notTunable = !SLibBlockParameterIsTunable(DelayTime)
%assign hasZeroDelay = (ParamSettings.DirectFeedThrough == "yes")
%assign allDelayAreZeros = (blockWidth == 1)
%assign notTunableZeroDelay = notTunable && hasZeroDelay && allDelayAreZeros
%if !notTunableZeroDelay
real_T **uBuffer = (real_T**)&%<LibBlockPWork(TUbufferPtrs,"","",0)>;
real_T **tBuffer = (real_T**)&%<LibBlockPWork(TUbufferPtrs,"","",blockWidth)>;
real_T simTime = %<LibGetT()>;
real_T tMinusDelay %<tMinusDelayValue>;
%endif
%if ::CompiledModel.StartTime != 0.0
%assign tStart = RTMGet("TStart")
%else
%assign tStart = 0.0
%endif
%if ParamSettings.DirectFeedThrough == "no"
%assign rollVars = ["y0","/DelayTime",...
"/InitialOutput ", "/Tail","/Head",...
"/Last","/CircularBufSize"]
%else
%assign rollVars = ["y0","u0","/DelayTime",...
"/InitialOutput","/Tail","/Head",...
"/Last","/CircularBufSize"]
%endif
%roll idx = RollRegions, lcv = localRollThreshold, block, "Roller", rollVars
%assign tail = LibBlockIWork(Tail, "", lcv, idx)
%assign head = LibBlockIWork(Head, "", lcv, idx)
%assign last = LibBlockIWork(Last, "", lcv, idx)
%assign initOutput = LibBlockParameter(InitialOutput, "",lcv,idx)
%assign y = LibBlockOutputSignal(0, "", lcv, idx)
%if lcv == ""
%assign paramSettingIdx = idx
%else
%if idx == 0
%assign paramSettingIdx = lcv
%else
%assign paramSettingIdx = "%<lcv> + %<idx>"
%endif
%endif
%if useConstIsDiscVect
%assign isDiscrete = "isDiscrete[%<paramSettingIdx>]"
%else
%assign isDiscrete = (SIZE(ParamSettings.DiscreteInput,1) == 1? ...
ParamSettings.DiscreteInput[0]: ...
ParamSettings.DiscreteInput[paramSettingIdx])
%endif
%assign bufSz = LibBlockIWork(CircularBufSize, "", lcv, idx)
%if ( Accelerator || isRSim || ...
CodeFormat == "S-Function" || ...
SolverType == "VariableStep" || ...
IsModelReferenceForASimstructBasedTarget() )
%assign minorStepAndTAtLastMajorOutput = ...
"(boolean_T) " ...
"(%<RTMIs("MinorTimeStep")> && " ...
"(%<RTMGet("TimeOfLastOutput")> == %<LibGetT()>))"
%else
%assign minorStepAndTAtLastMajorOutput = 0
%endif
%if tMinusDelayValue == ""
%assign delay = LibBlockParameter(DelayTime, "", lcv, idx)
%if FcnIsReal(delay)
%if %<delay> > 0.0
tMinusDelay = simTime - %<delay>;
%else
tMinusDelay = simTime;
%endif
%else
tMinusDelay = ((%<delay> > 0.0) ? %<delay> : 0.0);
tMinusDelay = simTime - tMinusDelay;
%endif
%endif
%assign utilName = TDelay_Interpolate(block)
%if (!SLibBlockParameterIsTunable(DelayTime)) && (blockWidth == 1)
%if ParamSettings.DirectFeedThrough == "no"
%<y> = %<utilName>(
tMinusDelay,
%<tStart>,
*tBuffer,
*uBuffer,
%<bufSz>,
&%<last>,
%<tail>,
%<head>,
%<initOutput>,
%<isDiscrete>,
%<minorStepAndTAtLastMajorOutput>);
%else
%assign u0 = LibBlockInputSignal(0, "", lcv, idx)
/* Delay time is 0 and inline parameter is on */
%<y> = %<u0>;
%endif
%else
%if ParamSettings.DirectFeedThrough == "yes"
if (%<delay> == 0.0)
%assign u0 = LibBlockInputSignal(0, "", lcv, idx)
%<y> = %<u0>;
else
%endif
%<y> = %<utilName>(
tMinusDelay,
%<tStart>,
*tBuffer,
*uBuffer,
%<bufSz>,
&%<last>,
%<tail>,
%<head>,
%<initOutput>,
%<isDiscrete>,
%<minorStepAndTAtLastMajorOutput>);
%endif
%if (lcv != "") || (lcv == "" && idx < blockWidth-1)
tBuffer++; uBuffer++;
%endif
%endroll
}
%endfunction
%function Update(block, system) Output
{
%assign blockWidth = LibBlockOutputSignalWidth(0)
%assign inport0Width = LibBlockInputSignalWidth(0)
real_T **uBuffer = (real_T**)&%<LibBlockPWork(TUbufferPtrs,"","",0)>;
real_T **tBuffer = (real_T**)&%<LibBlockPWork(TUbufferPtrs,"","",...
blockWidth)>;
real_T simTime = %<LibGetT()>;
%if (ParamSettings.FixedBuffer == "yes" )
%assign isFixedbuf = TLC_TRUE
boolean_T bufferisfull = %;
%else
%assign isFixedbuf = TLC_FALSE
%endif
%assign rollVars = ["u0", "/Tail","/Head", ...
"/CircularBufSize"]
%if Accelerator || isRSim
%assign delayPrm = "DelayTime"
%assign rollVars = ["u0", "/Tail","/Head", ...
"/Last", "/CircularBufSize", "/%<delayPrm>"]
%assign maxNewBufSz = LibBlockIWork(MaxNewBufSize, "", "", 0)
%endif
%roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
%assign tail = LibBlockIWork(Tail, "", lcv, idx)
%assign head = LibBlockIWork(Head, "", lcv, idx)
%assign bufSz = LibBlockIWork(CircularBufSize, "", lcv, idx)
%<head> = ((%<head> < (%<bufSz>-1)) ? (%<head>+1) : 0);
if (%<head> == %<tail>) {
%if isFixedbuf
bufferisfull = %;
%endif
%if Accelerator || isRSim
%assign last = LibBlockIWork(Last, "", lcv, idx)
%assign tDelay = LibBlockParameter(%<delayPrm>, "", lcv, idx)
%assign tMinusDelay = "simTime - %<tDelay>"
%assign utilName = TDelay_UpdateTailOrGrowBuf(block)
if (!%<utilName>( &%<bufSz>, ...
&%<tail>, &%<head>, &%<last>, %<tMinusDelay>, ...
tBuffer, uBuffer, %<SLibGetNullDefinitionFromTfl()>, (boolean_T)%<isFixedbuf>, ...
%, &%<maxNewBufSz>)) {
%<RTMSetErrStat("/"tdelay memory allocation error/"")>;
return;
}
%else
%<tail> = ((%<tail> < (%<bufSz>-1)) ? (%<tail>+1) : 0);
%endif
}
%if (lcv != "") || (lcv == "" && idx < blockWidth-1)
%assign pp = "++"
%else
%assign pp = ""
%endif
(*tBuffer%<pp>)[%<head>] = simTime;
%if (inport0Width == 1)
(*uBuffer%<pp>)[%<head>] = %<LibBlockInputSignal(0, "", "", 0)>;
%else
(*uBuffer%<pp>)[%<head>] = %<LibBlockInputSignal(0, "", lcv, idx)>;
%endif
%endroll
%if isFixedbuf
if (bufferisfull){
%<RTMSetBlockStateForSolverChangedAtMajorStep()>;
%<RTMSetContTimeOutputInconsistentWithStateAtMajorStep()>;
}
%endif
}
%endfunction
%function Terminate(block, system) Output
%<TDelay_Terminate(block, system)>
%endfunction