/*
 * Academic License - for use in teaching, academic research, and meeting
 * course requirements at degree granting institutions only.  Not for
 * government, commercial, or other organizational use.
 *
 * File: Modell.c
 *
 * Code generated for Simulink model 'Modell'.
 *
 * Model version                  : 1.26
 * Simulink Coder version         : 24.2 (R2024b) 21-Jun-2024
 * C/C++ source code generated on : Fri Feb  7 09:14:10 2025
 *
 * Target selection: ert.tlc
 * Embedded hardware selection: Atmel->AVR
 * Code generation objectives: Unspecified
 * Validation result: Not run
 */

#include "Modell.h"
#include <math.h>
#include "rtwtypes.h"
#include "Modell_private.h"

/* Block signals (default storage) */
B_Modell_T Modell_B;

/* Block states (default storage) */
DW_Modell_T Modell_DW;

/* Real-time model */
static RT_MODEL_Modell_T Modell_M_;
RT_MODEL_Modell_T *const Modell_M = &Modell_M_;
real_T look1_tu16DdId_binlcpw(real_T u0, const real_T bp0[], const uint16_T
  table[], uint32_T maxIndex)
{
  real_T frac;
  uint32_T bpIdx;
  uint32_T iLeft;
  uint32_T iRght;
  uint16_T yL_0d0;

  /* Column-major Lookup 1-D
     Search method: 'binary'
     Use previous index: 'off'
     Interpolation method: 'Linear point-slope'
     Extrapolation method: 'Clip'
     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: 'Clip'
     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[0UL]) {
    iLeft = 0UL;
    frac = 0.0;
  } else if (u0 < bp0[maxIndex]) {
    /* Binary Search */
    bpIdx = maxIndex >> 1UL;
    iLeft = 0UL;
    iRght = maxIndex;
    while (iRght - iLeft > 1UL) {
      if (u0 < bp0[bpIdx]) {
        iRght = bpIdx;
      } else {
        iLeft = bpIdx;
      }

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

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

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

/* Model step function */
void Modell_step(void)
{
  int16_T rowIdx;
  uint16_T b_varargout_1;
  boolean_T rtb_LogicalOperator;

  /* MATLABSystem: '<Root>/Analogeingang FSR402' */
  Modell_DW.obj_p.AnalogInDriverObj.MW_ANALOGIN_HANDLE = MW_AnalogIn_GetHandle
    (14UL);
  MW_AnalogInSingle_ReadResult
    (Modell_DW.obj_p.AnalogInDriverObj.MW_ANALOGIN_HANDLE, &b_varargout_1,
     MW_ANALOGIN_UINT16);

  /* MATLAB Function: '<Root>/MATLAB Function1' incorporates:
   *  DataTypeConversion: '<Root>/Data Type Conversion'
   *  MATLABSystem: '<Root>/Analogeingang FSR402'
   * */
  Modell_DW.sum_buffer = (Modell_DW.sum_buffer - Modell_DW.buffer[0]) + (real_T)
    b_varargout_1;
  for (rowIdx = 0; rowIdx < 39; rowIdx++) {
    Modell_DW.buffer[rowIdx] = Modell_DW.buffer[rowIdx + 1];
  }

  Modell_DW.buffer[39] = b_varargout_1;

  /* Product: '<Root>/Product' incorporates:
   *  Constant: '<Root>/Constant'
   *  Constant: '<Root>/Constant1'
   *  Lookup_n-D: '<Root>/1-D Lookup Table'
   *  MATLAB Function: '<Root>/MATLAB Function1'
   *  Product: '<Root>/Divide'
   */
  Modell_B.KraftinN = look1_tu16DdId_binlcpw(Modell_DW.sum_buffer / 40.0,
    Modell_P.uDLookupTable_bp01Data, Modell_P.uDLookupTable_tableData, 25UL) /
    Modell_P.Constant1_Value * Modell_P.Constant_Value;

  /* Logic: '<Root>/Logical Operator' incorporates:
   *  Abs: '<Root>/Abs'
   *  Constant: '<Root>/Constant2'
   *  Constant: '<Root>/Constant3'
   *  RelationalOperator: '<Root>/Relational Operator'
   *  RelationalOperator: '<Root>/Relational Operator1'
   *  Sum: '<S1>/Diff'
   *  UnitDelay: '<S1>/UD'
   *
   * Block description for '<S1>/Diff':
   *
   *  Add in CPU
   *
   * Block description for '<S1>/UD':
   *
   *  Store in Global RAM
   */
  rtb_LogicalOperator = ((fabs(Modell_B.KraftinN - Modell_DW.UD_DSTATE) <=
    Modell_P.Constant2_Value) && (Modell_B.KraftinN >= Modell_P.Constant3_Value));

  /* CombinatorialLogic: '<S3>/Logic' incorporates:
   *  Delay: '<Root>/Delay'
   *  Memory: '<S3>/Memory'
   */
  rowIdx = (int16_T)(((((uint16_T)rtb_LogicalOperator << 1) +
                       Modell_DW.Delay_DSTATE[0]) << 1) +
                     Modell_DW.Memory_PreviousInput);
  Modell_B.Logic[0U] = Modell_P.Logic_table[(uint16_T)rowIdx];
  Modell_B.Logic[1U] = Modell_P.Logic_table[(uint16_T)rowIdx + 8U];

  /* MATLABSystem: '<Root>/Lautsprecher' */
  writeDigitalPin(3, (uint8_T)Modell_B.Logic[0]);

  /* MATLABSystem: '<Root>/LCD_DDAppGeneratedBlock' */
  if (Modell_DW.obj.SampleTime != Modell_P.LCD_DDAppGeneratedBlock_SampleT) {
    Modell_DW.obj.SampleTime = Modell_P.LCD_DDAppGeneratedBlock_SampleT;
  }

  /*         %% Define output properties */
  stepFunctionLCD(Modell_B.KraftinN, 1.0);

  /* End of MATLABSystem: '<Root>/LCD_DDAppGeneratedBlock' */
  /* Update for UnitDelay: '<S1>/UD'
   *
   * Block description for '<S1>/UD':
   *
   *  Store in Global RAM
   */
  Modell_DW.UD_DSTATE = Modell_B.KraftinN;

  /* Update for Delay: '<Root>/Delay' */
  Modell_DW.Delay_DSTATE[0] = Modell_DW.Delay_DSTATE[1];
  Modell_DW.Delay_DSTATE[1] = Modell_DW.Delay_DSTATE[2];
  Modell_DW.Delay_DSTATE[2] = Modell_DW.Delay_DSTATE[3];
  Modell_DW.Delay_DSTATE[3] = Modell_DW.Delay_DSTATE[4];
  Modell_DW.Delay_DSTATE[4] = rtb_LogicalOperator;

  /* Update for Memory: '<S3>/Memory' */
  Modell_DW.Memory_PreviousInput = Modell_B.Logic[0];

  /* 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.
   */
  Modell_M->Timing.taskTime0 =
    ((time_T)(++Modell_M->Timing.clockTick0)) * Modell_M->Timing.stepSize0;
}

/* Model initialize function */
void Modell_initialize(void)
{
  /* Registration code */
  rtmSetTFinal(Modell_M, -1);
  Modell_M->Timing.stepSize0 = 0.01;

  /* External mode info */
  Modell_M->Sizes.checksums[0] = (2558251148U);
  Modell_M->Sizes.checksums[1] = (2395107127U);
  Modell_M->Sizes.checksums[2] = (1802213688U);
  Modell_M->Sizes.checksums[3] = (542120794U);

  {
    static const sysRanDType rtAlwaysEnabled = SUBSYS_RAN_BC_ENABLE;
    static RTWExtModeInfo rt_ExtModeInfo;
    static const sysRanDType *systemRan[5];
    Modell_M->extModeInfo = (&rt_ExtModeInfo);
    rteiSetSubSystemActiveVectorAddresses(&rt_ExtModeInfo, systemRan);
    systemRan[0] = &rtAlwaysEnabled;
    systemRan[1] = &rtAlwaysEnabled;
    systemRan[2] = &rtAlwaysEnabled;
    systemRan[3] = &rtAlwaysEnabled;
    systemRan[4] = &rtAlwaysEnabled;
    rteiSetModelMappingInfoPtr(Modell_M->extModeInfo,
      &Modell_M->SpecialInfo.mappingInfo);
    rteiSetChecksumsPtr(Modell_M->extModeInfo, Modell_M->Sizes.checksums);
    rteiSetTFinalTicks(Modell_M->extModeInfo, -1);
  }

  {
    int16_T i;

    /* InitializeConditions for UnitDelay: '<S1>/UD'
     *
     * Block description for '<S1>/UD':
     *
     *  Store in Global RAM
     */
    Modell_DW.UD_DSTATE = Modell_P.Difference_ICPrevInput;

    /* InitializeConditions for Delay: '<Root>/Delay' */
    for (i = 0; i < 5; i++) {
      Modell_DW.Delay_DSTATE[i] = Modell_P.Delay_InitialCondition;
    }

    /* End of InitializeConditions for Delay: '<Root>/Delay' */

    /* InitializeConditions for Memory: '<S3>/Memory' */
    Modell_DW.Memory_PreviousInput = Modell_P.SRFlipFlop_initial_condition;

    /* Start for MATLABSystem: '<Root>/Analogeingang FSR402' */
    Modell_DW.obj_p.matlabCodegenIsDeleted = false;
    Modell_DW.obj_p.isInitialized = 1L;
    Modell_DW.obj_p.AnalogInDriverObj.MW_ANALOGIN_HANDLE =
      MW_AnalogInSingle_Open(14UL);
    Modell_DW.obj_p.isSetupComplete = true;

    /* Start for MATLABSystem: '<Root>/Lautsprecher' */
    Modell_DW.obj_a.matlabCodegenIsDeleted = false;
    Modell_DW.obj_a.isInitialized = 1L;
    digitalIOSetup(3, 1);
    Modell_DW.obj_a.isSetupComplete = true;

    /* Start for MATLABSystem: '<Root>/LCD_DDAppGeneratedBlock' */
    /*  Constructor */
    Modell_DW.obj.matlabCodegenIsDeleted = false;
    Modell_DW.obj.SampleTime = Modell_P.LCD_DDAppGeneratedBlock_SampleT;
    Modell_DW.obj.isInitialized = 1L;

    /*         %% Define output properties */
    /*   Check the input size */
    setupFunctionLCD();
    Modell_DW.obj.isSetupComplete = true;
  }
}

/* Model terminate function */
void Modell_terminate(void)
{
  /* Terminate for MATLABSystem: '<Root>/Analogeingang FSR402' */
  if (!Modell_DW.obj_p.matlabCodegenIsDeleted) {
    Modell_DW.obj_p.matlabCodegenIsDeleted = true;
    if ((Modell_DW.obj_p.isInitialized == 1L) && Modell_DW.obj_p.isSetupComplete)
    {
      Modell_DW.obj_p.AnalogInDriverObj.MW_ANALOGIN_HANDLE =
        MW_AnalogIn_GetHandle(14UL);
      MW_AnalogIn_Close(Modell_DW.obj_p.AnalogInDriverObj.MW_ANALOGIN_HANDLE);
    }
  }

  /* End of Terminate for MATLABSystem: '<Root>/Analogeingang FSR402' */

  /* Terminate for MATLABSystem: '<Root>/Lautsprecher' */
  if (!Modell_DW.obj_a.matlabCodegenIsDeleted) {
    Modell_DW.obj_a.matlabCodegenIsDeleted = true;
  }

  /* End of Terminate for MATLABSystem: '<Root>/Lautsprecher' */
  /* Terminate for MATLABSystem: '<Root>/LCD_DDAppGeneratedBlock' */
  if (!Modell_DW.obj.matlabCodegenIsDeleted) {
    Modell_DW.obj.matlabCodegenIsDeleted = true;
  }

  /* End of Terminate for MATLABSystem: '<Root>/LCD_DDAppGeneratedBlock' */
}

/*
 * File trailer for generated code.
 *
 * [EOF]
 */
