/*
 * Kennfeld.c
 *
 * Real-Time Workshop code generation for Simulink model "Kennfeld.mdl".
 *
 * Model Version              : 1.10
 * Real-Time Workshop version : 7.3  (R2009a)  15-Jan-2009
 * C source code generated on : Thu Oct 22 11:13:33 2009
 *
 * Target selection: grt.tlc
 *   Note: GRT includes extra infrastructure and instrumentation for prototyping
 * Embedded hardware selection: 32-bit Generic
 * Code generation objectives: Unspecified
 * Validation result: Not run
 */

#include "Kennfeld.h"
#include "Kennfeld_private.h"

/* External inputs (root inport signals with auto storage) */
ExternalInputs_Kennfeld Kennfeld_U;

/* External outputs (root outports fed by signals with auto storage) */
ExternalOutputs_Kennfeld Kennfeld_Y;

/* Real-time model */
RT_MODEL_Kennfeld Kennfeld_M_;
RT_MODEL_Kennfeld *Kennfeld_M = &Kennfeld_M_;
real_T look2_binlx(real_T u0, real_T u1, const real_T bp0[], const real_T bp1[],
                   const real_T table[], const uint32_T maxIndex[], uint32_T
                   stride)
{
  real_T y;
  uint32_T bpIdx;
  real_T frac;
  uint32_T bpIndices[2];
  real_T fractions[2];

  /* Lookup 2-D
     Search method: 'binary'
     Use previous index: 'off'
     Interpolation method: 'Linear'
     Extrapolation method: 'Linear'
     Use last breakpoint for index at or above upper limit: 'off'
   */
  bpIdx = plook_binx(u0, bp0, maxIndex[0U], &frac);
  fractions[0U] = frac;
  bpIndices[0U] = bpIdx;
  bpIdx = plook_binx(u1, bp1, maxIndex[1U], &frac);
  fractions[1U] = frac;
  bpIndices[1U] = bpIdx;
  y = intrp2d_l_pw(&bpIndices[0U], &fractions[0U], table, stride);
  return y;
}

uint32_T plook_binx(real_T u, const real_T bp[], uint32_T maxIndex, real_T
                    *fraction)
{
  uint32_T bpIndex;

  /* Prelookup - Index and Fraction
     Index Search method: 'binary'
     Process out of range input: 'Linear extrapolation'
     Use previous index: 'off'
     Use last breakpoint for index at or above upper limit: 'off'
   */
  if (u < bp[0U]) {
    bpIndex = 0U;
    *fraction = (u - bp[0U]) / (bp[1U] - bp[0U]);
  } else if (u < bp[maxIndex]) {
    bpIndex = binsearch_u32d(u, bp, (maxIndex + 1U) >> 1U, maxIndex);
    *fraction = (u - bp[bpIndex]) / (bp[bpIndex + 1U] - bp[bpIndex]);
  } else {
    bpIndex = maxIndex - 1U;
    *fraction = (u - bp[maxIndex - 1U]) / (bp[maxIndex] - bp[maxIndex - 1U]);
  }

  return bpIndex;
}

real_T intrp2d_l_pw(const uint32_T bpIndex[], const real_T frac[], const real_T
                    table[], uint32_T stride)
{
  real_T y;
  uint32_T offset_1d;
  real_T yL_0d0;
  real_T yL_0d1;

  /* Interpolation 2-D
     Interpolation method: 'Linear'
     Use last breakpoint for index at or above upper limit: 'off'
     Overflow mode: 'portable wrapping'
   */
  offset_1d = bpIndex[1] * stride + bpIndex[0];
  yL_0d0 = table[offset_1d];
  yL_0d0 = (table[offset_1d + 1U] - yL_0d0) * frac[0] + yL_0d0;
  offset_1d = offset_1d + stride;
  yL_0d1 = table[offset_1d];
  y = (((table[offset_1d + 1U] - yL_0d1) * frac[0] + yL_0d1) - yL_0d0) * frac[1]
    + yL_0d0;
  return y;
}

uint32_T binsearch_u32d(real_T u, const real_T bp[], uint32_T startIndex,
  uint32_T maxIndex)
{
  uint32_T bpIndex;
  uint32_T iRght;
  uint32_T iLeft;
  uint32_T bpIdx;

  /* Binary Search */
  bpIdx = startIndex;
  iLeft = 0U;
  iRght = maxIndex;
  while (iRght - iLeft > 1U) {
    if (u < bp[bpIdx]) {
      iRght = bpIdx;
    } else {
      iLeft = bpIdx;
    }

    bpIdx = (iRght + iLeft) >> 1U;
  }

  bpIndex = iLeft;
  return bpIndex;
}

/* Model output function */
static void Kennfeld_output(int_T tid)
{
  /* Outport: '<Root>/frequenz' incorporates:
   *  Inport: '<Root>/ventil'
   *  Inport: '<Root>/visko'
   *  Lookup_n-D: '<Root>/Lookup Table (n-D)'
   */
  Kennfeld_Y.frequenz = look2_binlx(Kennfeld_U.ventil, Kennfeld_U.visko,
    &Kennfeld_P.LookupTablenD_bp01Data[0], &Kennfeld_P.LookupTablenD_bp02Data[0],
    &Kennfeld_P.LookupTablenD_tableData[0], &Kennfeld_P.LookupTablenD_maxIndex[0],
    45U);

  /* tid is required for a uniform function interface.
   * Argument tid is not used in the function. */
  UNUSED_PARAMETER(tid);
}

/* Model update function */
static void Kennfeld_update(int_T tid)
{
  /* Update absolute time for base rate */
  /* The "clockTick0" counts the number of times the code of this task has
   * been executed. The absolute time is the multiplication of "clockTick0"
   * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
   * overflow during the application lifespan selected.
   * Timer of this task consists of two 32 bit unsigned integers.
   * The two integers represent the low bits Timing.clockTick0 and the high bits
   * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
   */
  if (!(++Kennfeld_M->Timing.clockTick0))
    ++Kennfeld_M->Timing.clockTickH0;
  Kennfeld_M->Timing.t[0] = Kennfeld_M->Timing.clockTick0 *
    Kennfeld_M->Timing.stepSize0 + Kennfeld_M->Timing.clockTickH0 *
    Kennfeld_M->Timing.stepSize0 * 4294967296.0;

  /* tid is required for a uniform function interface.
   * Argument tid is not used in the function. */
  UNUSED_PARAMETER(tid);
}

/* Model initialize function */
void Kennfeld_initialize(boolean_T firstTime)
{
  (void)firstTime;

  /* Registration code */

  /* initialize non-finites */
  rt_InitInfAndNaN(sizeof(real_T));

  /* initialize real-time model */
  (void) memset((void *)Kennfeld_M,0,
                sizeof(RT_MODEL_Kennfeld));

  /* Initialize timing info */
  {
    int_T *mdlTsMap = Kennfeld_M->Timing.sampleTimeTaskIDArray;
    mdlTsMap[0] = 0;
    Kennfeld_M->Timing.sampleTimeTaskIDPtr = (&mdlTsMap[0]);
    Kennfeld_M->Timing.sampleTimes = (&Kennfeld_M->Timing.sampleTimesArray[0]);
    Kennfeld_M->Timing.offsetTimes = (&Kennfeld_M->Timing.offsetTimesArray[0]);

    /* task periods */
    Kennfeld_M->Timing.sampleTimes[0] = (0.1);

    /* task offsets */
    Kennfeld_M->Timing.offsetTimes[0] = (0.0);
  }

  rtmSetTPtr(Kennfeld_M, &Kennfeld_M->Timing.tArray[0]);

  {
    int_T *mdlSampleHits = Kennfeld_M->Timing.sampleHitArray;
    mdlSampleHits[0] = 1;
    Kennfeld_M->Timing.sampleHits = (&mdlSampleHits[0]);
  }

  rtmSetTFinal(Kennfeld_M, 10.0);
  Kennfeld_M->Timing.stepSize0 = 0.1;

  /* Setup for data logging */
  {
    static RTWLogInfo rt_DataLoggingInfo;
    Kennfeld_M->rtwLogInfo = &rt_DataLoggingInfo;
    rtliSetLogXSignalInfo(Kennfeld_M->rtwLogInfo, (NULL));
    rtliSetLogXSignalPtrs(Kennfeld_M->rtwLogInfo, (NULL));
    rtliSetLogT(Kennfeld_M->rtwLogInfo, "tout");
    rtliSetLogX(Kennfeld_M->rtwLogInfo, "");
    rtliSetLogXFinal(Kennfeld_M->rtwLogInfo, "");
    rtliSetSigLog(Kennfeld_M->rtwLogInfo, "");
    rtliSetLogVarNameModifier(Kennfeld_M->rtwLogInfo, "rt_");
    rtliSetLogFormat(Kennfeld_M->rtwLogInfo, 0);
    rtliSetLogMaxRows(Kennfeld_M->rtwLogInfo, 1000);
    rtliSetLogDecimation(Kennfeld_M->rtwLogInfo, 1);

    /*
     * Set pointers to the data and signal info for each output
     */
    {
      static void * rt_LoggedOutputSignalPtrs[] = {
        &Kennfeld_Y.frequenz
      };

      rtliSetLogYSignalPtrs(Kennfeld_M->rtwLogInfo, ((LogSignalPtrsType)
        rt_LoggedOutputSignalPtrs));
    }

    {
      static int_T rt_LoggedOutputWidths[] = {
        1
      };

      static int_T rt_LoggedOutputNumDimensions[] = {
        1
      };

      static int_T rt_LoggedOutputDimensions[] = {
        1
      };

      static boolean_T rt_LoggedOutputIsVarDims[] = {
        0
      };

      static int_T* rt_LoggedCurrentSignalDimensions[] = {
        (NULL)
      };

      static BuiltInDTypeId rt_LoggedOutputDataTypeIds[] = {
        SS_DOUBLE
      };

      static int_T rt_LoggedOutputComplexSignals[] = {
        0
      };

      static const char_T *rt_LoggedOutputLabels[] = {
        "" };

      static const char_T *rt_LoggedOutputBlockNames[] = {
        "Kennfeld/frequenz" };

      static RTWLogDataTypeConvert rt_RTWLogDataTypeConvert[] = {
        { 0, SS_DOUBLE, SS_DOUBLE, 0, 0, 0, 1.0, 0, 0.0 }
      };

      static RTWLogSignalInfo rt_LoggedOutputSignalInfo[] = {
        {
          1,
          rt_LoggedOutputWidths,
          rt_LoggedOutputNumDimensions,
          rt_LoggedOutputDimensions,
          rt_LoggedOutputIsVarDims,
          rt_LoggedCurrentSignalDimensions,
          rt_LoggedOutputDataTypeIds,
          rt_LoggedOutputComplexSignals,
          (NULL),

          { rt_LoggedOutputLabels },
          (NULL),
          (NULL),
          (NULL),

          { rt_LoggedOutputBlockNames },

          { (NULL) },
          (NULL),
          rt_RTWLogDataTypeConvert
        }
      };

      rtliSetLogYSignalInfo(Kennfeld_M->rtwLogInfo, rt_LoggedOutputSignalInfo);

      /* set currSigDims field */
      rt_LoggedCurrentSignalDimensions[0] = &rt_LoggedOutputWidths[0];
    }

    rtliSetLogY(Kennfeld_M->rtwLogInfo, "yout");
  }

  Kennfeld_M->solverInfoPtr = (&Kennfeld_M->solverInfo);
  Kennfeld_M->Timing.stepSize = (0.1);
  rtsiSetFixedStepSize(&Kennfeld_M->solverInfo, 0.1);
  rtsiSetSolverMode(&Kennfeld_M->solverInfo, SOLVER_MODE_SINGLETASKING);

  /* parameters */
  Kennfeld_M->ModelData.defaultParam = ((real_T *) &Kennfeld_P);

  /* external inputs */
  Kennfeld_M->ModelData.inputs = (((void*) &Kennfeld_U));
  (void) memset((void *)&Kennfeld_U, 0,
                sizeof(ExternalInputs_Kennfeld));

  /* external outputs */
  Kennfeld_M->ModelData.outputs = (&Kennfeld_Y);
  Kennfeld_Y.frequenz = 0.0;
}

/* Model terminate function */
void Kennfeld_terminate(void)
{
}

/*========================================================================*
 * Start of GRT compatible call interface                                 *
 *========================================================================*/
void MdlOutputs(int_T tid)
{
  Kennfeld_output(tid);
}

void MdlUpdate(int_T tid)
{
  Kennfeld_update(tid);
}

void MdlInitializeSizes(void)
{
  Kennfeld_M->Sizes.numContStates = (0);/* Number of continuous states */
  Kennfeld_M->Sizes.numY = (1);        /* Number of model outputs */
  Kennfeld_M->Sizes.numU = (2);        /* Number of model inputs */
  Kennfeld_M->Sizes.sysDirFeedThru = (1);/* The model is direct feedthrough */
  Kennfeld_M->Sizes.numSampTimes = (1);/* Number of sample times */
  Kennfeld_M->Sizes.numBlocks = (2);   /* Number of blocks */
  Kennfeld_M->Sizes.numBlockIO = (0);  /* Number of block outputs */
  Kennfeld_M->Sizes.numBlockPrms = (415);/* Sum of parameter "widths" */
}

void MdlInitializeSampleTimes(void)
{
}

void MdlInitialize(void)
{
}

void MdlStart(void)
{
  MdlInitialize();
}

RT_MODEL_Kennfeld *Kennfeld(void)
{
  Kennfeld_initialize(1);
  return Kennfeld_M;
}

void MdlTerminate(void)
{
  Kennfeld_terminate();
}

/*========================================================================*
 * End of GRT compatible call interface                                   *
 *========================================================================*/
