/*
 * PWM_sf.c
 *
 * Code generation for model "PWM_sf".
 *
 * Model version              : 1.825
 * Simulink Coder version : 9.4 (R2020b) 29-Jul-2020
 * C source code generated on : Fri Apr 14 12:53:29 2023
 *
 * Target selection: rtwsfcn.tlc
 * Note: GRT includes extra infrastructure and instrumentation for prototyping
 * Embedded hardware selection: ARM Compatible->ARM Cortex-M
 * Emulation hardware selection:
 *    Differs from embedded hardware (MATLAB Host)
 * Code generation objectives:
 *    1. Execution efficiency
 *    2. RAM efficiency
 * Validation result: Not run
 */

#include <math.h>
#include "PWM_sf.h"
#include "PWM_sf_private.h"
#include "simstruc.h"
#include "fixedpoint.h"
#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

extern void *PWM_malloc(SimStruct *S);

#endif

#ifndef __RTW_UTFREE__
#if defined (MATLAB_MEX_FILE)

extern void * utMalloc(size_t);
extern void utFree(void *);

#endif
#endif                                 /* #ifndef __RTW_UTFREE__ */

/* Forward declaration for local functions */
static real_T PWM_rt_remd_snf(real_T u0, real_T u1);

#if defined(MATLAB_MEX_FILE)
#include "rt_nonfinite.c"
#endif

static const char_T *RT_MEMORY_ALLOCATION_ERROR =
  "memory allocation error in generated S-Function";

/*
 * Time delay interpolation routine
 *
 * The linear interpolation is performed using the formula:
 *
 *          (t2 - tMinusDelay)         (tMinusDelay - t1)
 * u(t)  =  ----------------- * u1  +  ------------------- * u2
 *              (t2 - t1)                  (t2 - t1)
 */
real_T PWM_sf_rt_TDelayInterpolate(
  real_T tMinusDelay,                 /* tMinusDelay = currentSimTime - delay */
  real_T tStart,
  real_T *tBuf,
  real_T *uBuf,
  int_T bufSz,
  int_T *lastIdx,
  int_T oldestIdx,
  int_T newIdx,
  real_T initOutput,
  boolean_T discrete,
  boolean_T minorStepAndTAtLastMajorOutput)
{
  int_T i;
  real_T yout, t1, t2, u1, u2;

  /*
   * If there is only one data point in the buffer, this data point must be
   * the t= 0 and tMinusDelay > t0, it ask for something unknown. The best
   * guess if initial output as well
   */
  if ((newIdx == 0) && (oldestIdx ==0 ) && (tMinusDelay > tStart))
    return initOutput;

  /*
   * If tMinusDelay is less than zero, should output initial value
   */
  if (tMinusDelay <= tStart)
    return initOutput;

  /* For fixed buffer extrapolation:
   * if tMinusDelay is small than the time at oldestIdx, if discrete, output
   * tailptr value,  else use tailptr and tailptr+1 value to extrapolate
   * It is also for fixed buffer. Note: The same condition can happen for transport delay block where
   * use tStart and and t[tail] other than using t[tail] and t[tail+1].
   * See below
   */
  if ((tMinusDelay <= tBuf[oldestIdx] ) ) {
    if (discrete) {
      return(uBuf[oldestIdx]);
    } else {
      int_T tempIdx= oldestIdx + 1;
      if (oldestIdx == bufSz-1)
        tempIdx = 0;
      t1= tBuf[oldestIdx];
      t2= tBuf[tempIdx];
      u1= uBuf[oldestIdx];
      u2= uBuf[tempIdx];
      if (t2 == t1) {
        if (tMinusDelay >= t2) {
          yout = u2;
        } else {
          yout = u1;
        }
      } else {
        real_T f1 = (t2-tMinusDelay) / (t2-t1);
        real_T f2 = 1.0 - f1;

        /*
         * Use Lagrange's interpolation formula.  Exact outputs at t1, t2.
         */
        yout = f1*u1 + f2*u2;
      }

      return yout;
    }
  }

  /*
   * When block does not have direct feedthrough, we use the table of
   * values to extrapolate off the end of the table for delays that are less
   * than 0 (less then step size).  This is not completely accurate.  The
   * chain of events is as follows for a given time t.  Major output - look
   * in table.  Update - add entry to table.  Now, if we call the output at
   * time t again, there is a new entry in the table. For very small delays,
   * this means that we will have a different answer from the previous call
   * to the output fcn at the same time t.  The following code prevents this
   * from happening.
   */
  if (minorStepAndTAtLastMajorOutput) {
    /* pretend that the new entry has not been added to table */
    if (newIdx != 0) {
      if (*lastIdx == newIdx) {
        (*lastIdx)--;
      }

      newIdx--;
    } else {
      if (*lastIdx == newIdx) {
        *lastIdx = bufSz-1;
      }

      newIdx = bufSz - 1;
    }
  }

  i = *lastIdx;
  if (tBuf[i] < tMinusDelay) {
    /* Look forward starting at last index */
    while (tBuf[i] < tMinusDelay) {
      /* May occur if the delay is less than step-size - extrapolate */
      if (i == newIdx)
        break;
      i = ( i < (bufSz-1) ) ? (i+1) : 0;/* move through buffer */
    }
  } else {
    /*
     * Look backwards starting at last index which can happen when the
     * delay time increases.
     */
    while (tBuf[i] >= tMinusDelay) {
      /*
       * Due to the entry condition at top of function, we
       * should never hit the end.
       */
      i = (i > 0) ? i-1 : (bufSz-1);   /* move through buffer */
    }

    i = ( i < (bufSz-1) ) ? (i+1) : 0;
  }

  *lastIdx = i;
  if (discrete) {
    /*
     * tempEps = 128 * eps;
     * localEps = max(tempEps, tempEps*fabs(tBuf[i]))/2;
     */
    double tempEps = (DBL_EPSILON) * 128.0;
    double localEps = tempEps * fabs(tBuf[i]);
    if (tempEps > localEps) {
      localEps = tempEps;
    }

    localEps = localEps / 2.0;
    if (tMinusDelay >= (tBuf[i] - localEps)) {
      yout = uBuf[i];
    } else {
      if (i == 0) {
        yout = uBuf[bufSz-1];
      } else {
        yout = uBuf[i-1];
      }
    }
  } else {
    if (i == 0) {
      t1 = tBuf[bufSz-1];
      u1 = uBuf[bufSz-1];
    } else {
      t1 = tBuf[i-1];
      u1 = uBuf[i-1];
    }

    t2 = tBuf[i];
    u2 = uBuf[i];
    if (t2 == t1) {
      if (tMinusDelay >= t2) {
        yout = u2;
      } else {
        yout = u1;
      }
    } else {
      real_T f1 = (t2-tMinusDelay) / (t2-t1);
      real_T f2 = 1.0 - f1;

      /*
       * Use Lagrange's interpolation formula.  Exact outputs at t1, t2.
       */
      yout = f1*u1 + f2*u2;
    }
  }

  return(yout);
}

real_T PWM_look1_binlx(real_T u0, const real_T bp0[], const real_T table[],
  uint32_T maxIndex)
{
  real_T frac;
  real_T yL_0d0;
  uint32_T bpIdx;
  uint32_T iLeft;
  uint32_T iRght;

  /* Column-major Lookup 1-D
     Search method: 'binary'
     Use previous index: 'off'
     Interpolation method: 'Linear point-slope'
     Extrapolation method: 'Linear'
     Use last breakpoint for index at or above upper limit: 'off'
     Remove protection against out-of-range input in generated code: 'off'
   */
  /* Prelookup - Index and Fraction
     Index Search method: 'binary'
     Extrapolation method: 'Linear'
     Use previous index: 'off'
     Use last breakpoint for index at or above upper limit: 'off'
     Remove protection against out-of-range input in generated code: 'off'
   */
  if (u0 <= bp0[0U]) {
    iLeft = 0U;
    frac = (u0 - bp0[0U]) / (bp0[1U] - bp0[0U]);
  } else if (u0 < bp0[maxIndex]) {
    /* Binary Search */
    bpIdx = maxIndex >> 1U;
    iLeft = 0U;
    iRght = maxIndex;
    while (iRght - iLeft > 1U) {
      if (u0 < bp0[bpIdx]) {
        iRght = bpIdx;
      } else {
        iLeft = bpIdx;
      }

      bpIdx = (iRght + iLeft) >> 1U;
    }

    frac = (u0 - bp0[iLeft]) / (bp0[iLeft + 1U] - bp0[iLeft]);
  } else {
    iLeft = maxIndex - 1U;
    frac = (u0 - bp0[maxIndex - 1U]) / (bp0[maxIndex] - bp0[maxIndex - 1U]);
  }

  /* Column-major Interpolation 1-D
     Interpolation method: 'Linear point-slope'
     Use last breakpoint for index at or above upper limit: 'off'
     Overflow mode: 'wrapping'
   */
  yL_0d0 = table[iLeft];
  return (table[iLeft + 1U] - yL_0d0) * frac + yL_0d0;
}

static real_T PWM_rt_remd_snf(real_T u0, real_T u1)
{
  real_T q;
  real_T y;
  if (rtIsNaN(u0) || rtIsNaN(u1) || rtIsInf(u0)) {
    y = (rtNaN);
  } else if (rtIsInf(u1)) {
    y = u0;
  } else if ((u1 != 0.0) && (u1 != trunc(u1))) {
    q = fabs(u0 / u1);
    if (!(fabs(q - floor(q + 0.5)) > DBL_EPSILON * q)) {
      y = 0.0 * u0;
    } else {
      y = fmod(u0, u1);
    }
  } else {
    y = fmod(u0, u1);
  }

  return y;
}

/* Start for root system: '<Root>' */
#define MDL_START

static void mdlStart(SimStruct *S)
{
  /* instance underlying S-Function data */
#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
#if defined(MATLAB_MEX_FILE)

  /* non-finites */
  rt_InitInfAndNaN(sizeof(real_T));

  /* Check for invalid switching between solver types */
  if (ssIsVariableStepSolver(S)) {
    ssSetErrorStatus(S, "This Simulink Coder generated "
                     "S-Function cannot be used in a simulation with "
                     "a solver type of variable-step "
                     "because this S-Function was created from a model with "
                     "solver type of fixed-step and it has continuous time blocks. "
                     "See the Solver page of the simulation parameters dialog.");
    return;
  }

  if (fabs(ssGetFixedStepSize(S) - 5.0E-7) > mxGetEps()*100*5.0E-7) {
    ssSetErrorStatus(S, "This Simulink Coder generated "
                     "S-Function cannot be used in a simulation with "
                     "the current fixed step size "
                     "because this S-Function was created from a model with "
                     "a fixed step size of 5.0E-7 and had both "
                     "continuous blocks and discrete blocks running at this rate. "
                     "See the Solver page of the simulation parameters dialog.");
    return;
  }

#endif

  PWM_malloc(S);
  if (ssGetErrorStatus(S) != (NULL) ) {
    return;
  }

#endif

  {
    B_PWM_T *_rtB;
    _rtB = ((B_PWM_T *) ssGetLocalBlockIO(S));

    /* Start for TransportDelay: '<S2>/Transport Delay' */
    {
      real_T *pBuffer = &((real_T*) ssGetDWork(S, 0))[1];
      ((int_T*) ssGetDWork(S, 6))[0] = 0;
      ((int_T*) ssGetDWork(S, 6))[1] = 0;
      ((int_T*) ssGetDWork(S, 6))[2] = 0;
      ((int_T*) ssGetDWork(S, 6))[3] = 1024;
      pBuffer[0] = 0.0;
      pBuffer[1024] = ssGetT(S);
      ((void**) ssGetDWork(S, 3))[0] = (void *) &pBuffer[0];
      ((void**) ssGetDWork(S, 3))[1] = (void *) &pBuffer[1024];
    }

    /* Start for TransportDelay: '<S2>/Transport Delay1' */
    {
      real_T *pBuffer = &((real_T*) ssGetDWork(S, 1))[1];
      ((int_T*) ssGetDWork(S, 7))[0] = 0;
      ((int_T*) ssGetDWork(S, 7))[1] = 0;
      ((int_T*) ssGetDWork(S, 7))[2] = 0;
      ((int_T*) ssGetDWork(S, 7))[3] = 1024;
      pBuffer[0] = 0.0;
      pBuffer[1024] = ssGetT(S);
      ((void**) ssGetDWork(S, 4))[0] = (void *) &pBuffer[0];
      ((void**) ssGetDWork(S, 4))[1] = (void *) &pBuffer[1024];
    }

    /* Start for TransportDelay: '<S2>/Transport Delay2' */
    {
      real_T *pBuffer = &((real_T*) ssGetDWork(S, 2))[1];
      ((int_T*) ssGetDWork(S, 8))[0] = 0;
      ((int_T*) ssGetDWork(S, 8))[1] = 0;
      ((int_T*) ssGetDWork(S, 8))[2] = 0;
      ((int_T*) ssGetDWork(S, 8))[3] = 1024;
      pBuffer[0] = 0.0;
      pBuffer[1024] = ssGetT(S);
      ((void**) ssGetDWork(S, 5))[0] = (void *) &pBuffer[0];
      ((void**) ssGetDWork(S, 5))[1] = (void *) &pBuffer[1024];
    }
  }
}

/* Outputs for root system: '<Root>' */
static void mdlOutputs(SimStruct *S, int_T tid)
{
  /* local block i/o variables */
  real_T rtb_TransportDelay1;
  real_T rtb_TransportDelay2;
  real_T rtb_TransportDelay;
  B_PWM_T *_rtB;
  real_T expr_2_0_0;
  real_T rtb_Abs;
  real_T rtb_Abs2;
  boolean_T rtb_RelationalOperator;
  boolean_T rtb_RelationalOperator1;
  boolean_T rtb_RelationalOperator2;
  _rtB = ((B_PWM_T *) ssGetLocalBlockIO(S));
  if (ssIsContinuousTask(S, tid)) {
    /* S-Function (sfun_tstart): '<S3>/startTime' */
    /* S-Function Block (sfun_tstart): <S3>/startTime */
    expr_2_0_0 = ssGetTStart(S);

    /* Lookup_n-D: '<S3>/Look-Up Table1' incorporates:
     *  Clock: '<S3>/Clock'
     *  Constant: '<S3>/Constant'
     *  Math: '<S3>/Math Function'
     *  Sum: '<S3>/Sum'
     */
    expr_2_0_0 = PWM_look1_binlx(PWM_rt_remd_snf(ssGetT(S) - expr_2_0_0, 0.0001),
      PWM_ConstP.LookUpTable1_bp01Data, PWM_ConstP.LookUpTable1_tableData, 2U);

    /* RelationalOperator: '<S2>/Relational Operator' */
    rtb_RelationalOperator = (expr_2_0_0 > *((const real_T **)
      ssGetInputPortSignalPtrs(S, 0))[0]);

    /* TransportDelay: '<S2>/Transport Delay' */
    {
      real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 3))[0];
      real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 3))[1];
      real_T simTime = ssGetT(S);
      real_T tMinusDelay = simTime - 2.0E-6;
      rtb_TransportDelay = PWM_sf_rt_TDelayInterpolate(
        tMinusDelay,
        0.0,
        *tBuffer,
        *uBuffer,
        ((int_T*) ssGetDWork(S, 6))[3],
        &((int_T*) ssGetDWork(S, 6))[2],
        ((int_T*) ssGetDWork(S, 6))[0],
        ((int_T*) ssGetDWork(S, 6))[1],
        0.0,
        0,
        (boolean_T) (ssIsMinorTimeStep(S) && (ssGetTimeOfLastOutput(S) == ssGetT
        (S))));
    }

    /* DataTypeConversion: '<S2>/Data Type Conversion3' incorporates:
     *  Logic: '<S2>/Logical Operator'
     */
    rtb_Abs2 = !rtb_RelationalOperator;

    /* Abs: '<S2>/Abs' incorporates:
     *  DataTypeConversion: '<S2>/Data Type Conversion3'
     *  Sum: '<S2>/Subtract'
     */
    rtb_Abs = fabs(rtb_Abs2 - rtb_TransportDelay);

    /* Product: '<S2>/Product' */
    _rtB->Product = rtb_Abs2 * rtb_Abs;

    /* Product: '<S2>/Product1' */
    _rtB->Product1 = rtb_Abs * rtb_TransportDelay;

    /* RelationalOperator: '<S2>/Relational Operator1' */
    rtb_RelationalOperator1 = (expr_2_0_0 > *((const real_T **)
      ssGetInputPortSignalPtrs(S, 0))[1]);

    /* TransportDelay: '<S2>/Transport Delay1' */
    {
      real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 4))[0];
      real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 4))[1];
      real_T simTime = ssGetT(S);
      real_T tMinusDelay = simTime - 2.0E-6;
      rtb_TransportDelay1 = PWM_sf_rt_TDelayInterpolate(
        tMinusDelay,
        0.0,
        *tBuffer,
        *uBuffer,
        ((int_T*) ssGetDWork(S, 7))[3],
        &((int_T*) ssGetDWork(S, 7))[2],
        ((int_T*) ssGetDWork(S, 7))[0],
        ((int_T*) ssGetDWork(S, 7))[1],
        0.0,
        0,
        (boolean_T) (ssIsMinorTimeStep(S) && (ssGetTimeOfLastOutput(S) == ssGetT
        (S))));
    }

    /* RelationalOperator: '<S2>/Relational Operator2' */
    rtb_RelationalOperator2 = (expr_2_0_0 > *((const real_T **)
      ssGetInputPortSignalPtrs(S, 0))[2]);

    /* TransportDelay: '<S2>/Transport Delay2' */
    {
      real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 5))[0];
      real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 5))[1];
      real_T simTime = ssGetT(S);
      real_T tMinusDelay = simTime - 2.0E-6;
      rtb_TransportDelay2 = PWM_sf_rt_TDelayInterpolate(
        tMinusDelay,
        0.0,
        *tBuffer,
        *uBuffer,
        ((int_T*) ssGetDWork(S, 8))[3],
        &((int_T*) ssGetDWork(S, 8))[2],
        ((int_T*) ssGetDWork(S, 8))[0],
        ((int_T*) ssGetDWork(S, 8))[1],
        0.0,
        0,
        (boolean_T) (ssIsMinorTimeStep(S) && (ssGetTimeOfLastOutput(S) == ssGetT
        (S))));
    }

    /* DataTypeConversion: '<S2>/Data Type Conversion1' incorporates:
     *  Logic: '<S2>/Logical Operator1'
     *  ManualSwitch: '<S1>/Manual Switch'
     */
    rtb_Abs2 = !rtb_RelationalOperator1;

    /* Abs: '<S2>/Abs1' incorporates:
     *  DataTypeConversion: '<S2>/Data Type Conversion1'
     *  ManualSwitch: '<S1>/Manual Switch'
     *  Sum: '<S2>/Subtract1'
     */
    expr_2_0_0 = fabs(rtb_Abs2 - rtb_TransportDelay1);

    /* Outport: '<Root>/PWMb' incorporates:
     *  ManualSwitch: '<S1>/Manual Switch'
     *  Product: '<S2>/Product2'
     *  Product: '<S2>/Product3'
     */
    ((real_T *)ssGetOutputPortSignal(S, 0))[2] = rtb_Abs2 * expr_2_0_0;
    ((real_T *)ssGetOutputPortSignal(S, 0))[3] = expr_2_0_0 *
      rtb_TransportDelay1;

    /* DataTypeConversion: '<S2>/Data Type Conversion5' incorporates:
     *  Logic: '<S2>/Logical Operator2'
     *  ManualSwitch: '<S1>/Manual Switch'
     */
    expr_2_0_0 = !rtb_RelationalOperator2;

    /* Abs: '<S2>/Abs2' incorporates:
     *  ManualSwitch: '<S1>/Manual Switch'
     *  Sum: '<S2>/Subtract2'
     */
    rtb_Abs2 = fabs(expr_2_0_0 - rtb_TransportDelay2);

    /* Outport: '<Root>/PWMb' incorporates:
     *  ManualSwitch: '<S1>/Manual Switch'
     *  Product: '<S2>/Product4'
     *  Product: '<S2>/Product5'
     */
    ((real_T *)ssGetOutputPortSignal(S, 0))[0] = _rtB->Product;
    ((real_T *)ssGetOutputPortSignal(S, 0))[1] = _rtB->Product1;
    ((real_T *)ssGetOutputPortSignal(S, 0))[4] = expr_2_0_0 * rtb_Abs2;
    ((real_T *)ssGetOutputPortSignal(S, 0))[5] = rtb_Abs2 * rtb_TransportDelay2;

    /* DataTypeConversion: '<S2>/Data Type Conversion6' */
    _rtB->DataTypeConversion6 = rtb_RelationalOperator2;

    /* DataTypeConversion: '<S2>/Data Type Conversion2' */
    _rtB->DataTypeConversion2 = rtb_RelationalOperator1;
  }

  if (ssIsSampleHit(S, 1, tid)) {
  }

  if (ssIsContinuousTask(S, tid)) {
    /* DataTypeConversion: '<S2>/Data Type Conversion4' */
    _rtB->DataTypeConversion4 = rtb_RelationalOperator;
  }

  UNUSED_PARAMETER(tid);
}

/* Update for root system: '<Root>' */
#define MDL_UPDATE

static void mdlUpdate(SimStruct *S, int_T tid)
{
  B_PWM_T *_rtB;
  _rtB = ((B_PWM_T *) ssGetLocalBlockIO(S));
  if (ssIsContinuousTask(S, tid)) {
    /* Update for TransportDelay: '<S2>/Transport Delay' */
    {
      real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 3))[0];
      real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 3))[1];
      real_T simTime = ssGetT(S);
      ((int_T*) ssGetDWork(S, 6))[1] = ((((int_T*) ssGetDWork(S, 6))[1] <
        (((int_T*) ssGetDWork(S, 6))[3]-1)) ? (((int_T*) ssGetDWork(S, 6))[1]+1)
        : 0);
      if (((int_T*) ssGetDWork(S, 6))[1] == ((int_T*) ssGetDWork(S, 6))[0]) {
        ((int_T*) ssGetDWork(S, 6))[0] = ((((int_T*) ssGetDWork(S, 6))[0] <
          (((int_T*) ssGetDWork(S, 6))[3]-1)) ? (((int_T*) ssGetDWork(S, 6))[0]+
          1) : 0);
      }

      (*tBuffer)[((int_T*) ssGetDWork(S, 6))[1]] = simTime;
      (*uBuffer)[((int_T*) ssGetDWork(S, 6))[1]] = _rtB->DataTypeConversion4;
    }

    /* Update for TransportDelay: '<S2>/Transport Delay1' */
    {
      real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 4))[0];
      real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 4))[1];
      real_T simTime = ssGetT(S);
      ((int_T*) ssGetDWork(S, 7))[1] = ((((int_T*) ssGetDWork(S, 7))[1] <
        (((int_T*) ssGetDWork(S, 7))[3]-1)) ? (((int_T*) ssGetDWork(S, 7))[1]+1)
        : 0);
      if (((int_T*) ssGetDWork(S, 7))[1] == ((int_T*) ssGetDWork(S, 7))[0]) {
        ((int_T*) ssGetDWork(S, 7))[0] = ((((int_T*) ssGetDWork(S, 7))[0] <
          (((int_T*) ssGetDWork(S, 7))[3]-1)) ? (((int_T*) ssGetDWork(S, 7))[0]+
          1) : 0);
      }

      (*tBuffer)[((int_T*) ssGetDWork(S, 7))[1]] = simTime;
      (*uBuffer)[((int_T*) ssGetDWork(S, 7))[1]] = _rtB->DataTypeConversion2;
    }

    /* Update for TransportDelay: '<S2>/Transport Delay2' */
    {
      real_T **uBuffer = (real_T**)&((void**) ssGetDWork(S, 5))[0];
      real_T **tBuffer = (real_T**)&((void**) ssGetDWork(S, 5))[1];
      real_T simTime = ssGetT(S);
      ((int_T*) ssGetDWork(S, 8))[1] = ((((int_T*) ssGetDWork(S, 8))[1] <
        (((int_T*) ssGetDWork(S, 8))[3]-1)) ? (((int_T*) ssGetDWork(S, 8))[1]+1)
        : 0);
      if (((int_T*) ssGetDWork(S, 8))[1] == ((int_T*) ssGetDWork(S, 8))[0]) {
        ((int_T*) ssGetDWork(S, 8))[0] = ((((int_T*) ssGetDWork(S, 8))[0] <
          (((int_T*) ssGetDWork(S, 8))[3]-1)) ? (((int_T*) ssGetDWork(S, 8))[0]+
          1) : 0);
      }

      (*tBuffer)[((int_T*) ssGetDWork(S, 8))[1]] = simTime;
      (*uBuffer)[((int_T*) ssGetDWork(S, 8))[1]] = _rtB->DataTypeConversion6;
    }
  }

  UNUSED_PARAMETER(tid);
}

/* Termination for root system: '<Root>' */
static void mdlTerminate(SimStruct *S)
{
  B_PWM_T *_rtB;
  _rtB = ((B_PWM_T *) ssGetLocalBlockIO(S));

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)

  if (ssGetUserData(S) != (NULL) ) {
    rt_FREE(ssGetLocalBlockIO(S));
  }

  rt_FREE(ssGetUserData(S));

#endif

}

#if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
#include "PWM_mid.h"
#endif

/* Function to initialize sizes. */
static void mdlInitializeSizes(SimStruct *S)
{
  ssSetNumSampleTimes(S, 2);           /* Number of sample times */
  ssSetNumContStates(S, 0);            /* Number of continuous states */
  ssSetNumNonsampledZCs(S, 0);         /* Number of nonsampled ZCs */

  /* Number of output ports */
  if (!ssSetNumOutputPorts(S, 1))
    return;

  /* outport number: 0 */
  if (!ssSetOutputPortVectorDimension(S, 0, 6))
    return;
  if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) {
    ssSetOutputPortDataType(S, 0, SS_DOUBLE);
  }

  ssSetOutputPortSampleTime(S, 0, 0.0);
  ssSetOutputPortOffsetTime(S, 0, 0.0);
  ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);

  /* Number of input ports */
  if (!ssSetNumInputPorts(S, 1))
    return;

  /* inport number: 0 */
  {
    if (!ssSetInputPortVectorDimension(S, 0, 3))
      return;
    if (ssGetSimMode(S) != SS_SIMMODE_SIZES_CALL_ONLY) {
      ssSetInputPortDataType(S, 0, SS_DOUBLE);
    }

    ssSetInputPortDirectFeedThrough(S, 0, 1);
    ssSetInputPortSampleTime(S, 0, 5.0E-7);
    ssSetInputPortOffsetTime(S, 0, 0.0);
    ssSetInputPortOverWritable(S, 0, 0);
    ssSetInputPortOptimOpts(S, 0, SS_NOT_REUSABLE_AND_GLOBAL);
  }

  ssSetRTWGeneratedSFcn(S, 1);         /* Generated S-function */

  /* DWork */
  if (!ssSetNumDWork(S, 9)) {
    return;
  }

  /* '<S2>/Transport Delay': RWORK */
  ssSetDWorkName(S, 0, "DWORK0");
  ssSetDWorkWidth(S, 0, 2049);

  /* '<S2>/Transport Delay1': RWORK */
  ssSetDWorkName(S, 1, "DWORK1");
  ssSetDWorkWidth(S, 1, 2049);

  /* '<S2>/Transport Delay2': RWORK */
  ssSetDWorkName(S, 2, "DWORK2");
  ssSetDWorkWidth(S, 2, 2049);

  /* '<S2>/Transport Delay': PWORK */
  ssSetDWorkName(S, 3, "DWORK3");
  ssSetDWorkWidth(S, 3, 2);
  ssSetDWorkDataType(S, 3, SS_POINTER);

  /* '<S2>/Transport Delay1': PWORK */
  ssSetDWorkName(S, 4, "DWORK4");
  ssSetDWorkWidth(S, 4, 2);
  ssSetDWorkDataType(S, 4, SS_POINTER);

  /* '<S2>/Transport Delay2': PWORK */
  ssSetDWorkName(S, 5, "DWORK5");
  ssSetDWorkWidth(S, 5, 2);
  ssSetDWorkDataType(S, 5, SS_POINTER);

  /* '<S2>/Transport Delay': IWORK */
  ssSetDWorkName(S, 6, "DWORK6");
  ssSetDWorkWidth(S, 6, 4);
  ssSetDWorkDataType(S, 6, SS_INTEGER);

  /* '<S2>/Transport Delay1': IWORK */
  ssSetDWorkName(S, 7, "DWORK7");
  ssSetDWorkWidth(S, 7, 4);
  ssSetDWorkDataType(S, 7, SS_INTEGER);

  /* '<S2>/Transport Delay2': IWORK */
  ssSetDWorkName(S, 8, "DWORK8");
  ssSetDWorkWidth(S, 8, 4);
  ssSetDWorkDataType(S, 8, SS_INTEGER);

  /* Tunable Parameters */
  ssSetNumSFcnParams(S, 0);

  /* Number of expected parameters */
#if defined(MATLAB_MEX_FILE)

  if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {

#if defined(MDL_CHECK_PARAMETERS)

    mdlCheckParameters(S);

#endif                                 /* MDL_CHECK_PARAMETERS */

    if (ssGetErrorStatus(S) != (NULL) ) {
      return;
    }
  } else {
    return;                /* Parameter mismatch will be reported by Simulink */
  }

#endif                                 /* MATLAB_MEX_FILE */

  /* Options */
  ssSetOptions(S, (SS_OPTION_RUNTIME_EXCEPTION_FREE_CODE |
                   SS_OPTION_PORT_SAMPLE_TIMES_ASSIGNED ));

#if SS_SFCN_FOR_SIM

  {
    ssSupportsMultipleExecInstances(S, false);
    ssRegisterMsgForNotSupportingMultiExecInst(S,
      "<diag_root><diag id=\"Simulink:blocks:BlockDoesNotSupportMultiExecInstances\" pr=\"d\"><arguments><arg type=\"encoded\">UABXAE0ALwBQAFcATQAvAG0AbwBkAHUAbABhAHQAZQBkACAAdwBhAHYAZQAvAHMAdABhAHIAdABUAGkAbQBlAAAA</arg><arg type=\"encoded\">PABfAF8AaQBpAFMAUwBfAF8APgA8AC8AXwBfAGkAaQBTAFMAXwBfAD4AAAA=</arg><arg type=\"encoded\">PABfAF8AaQB0AGUAcgBCAGwAawBfAF8APgA8AC8AXwBfAGkAdABlAHIAQgBsAGsAXwBfAD4AAAA=</arg></arguments><hs><h>AAAACIDlzUD+</h></hs></diag></diag_root>");
    ssHasStateInsideForEachSS(S, false);
  }

#endif

}

/* Function to initialize sample times. */
static void mdlInitializeSampleTimes(SimStruct *S)
{
  /* task periods */
  ssSetSampleTime(S, 0, 0.0);
  ssSetSampleTime(S, 1, 5.0E-7);

  /* task offsets */
  ssSetOffsetTime(S, 0, 0.0);
  ssSetOffsetTime(S, 1, 0.0);
}

#if defined(MATLAB_MEX_FILE)
#include "fixedpoint.c"
#include "simulink.c"
#else
#undef S_FUNCTION_NAME
#define S_FUNCTION_NAME                PWM_sf
#include "cg_sfun.h"
#endif                                 /* defined(MATLAB_MEX_FILE) */
