/*
 * File: automats.c
 *
 * Code generated for Simulink model 'automats'.
 *
 * Model version                  : 1.33
 * Simulink Coder version         : 9.4 (R2020b) 29-Jul-2020
 * C/C++ source code generated on : Thu May 13 21:48:38 2021
 *
 * Target selection: ert.tlc
 * Embedded hardware selection: AMD->x86-64 (Windows64)
 * Code generation objectives:
 *    1. Execution efficiency
 *    2. RAM efficiency
 * Validation result: Not run
 */

#include "automats.h"
#include "get.h"
#include "set.h"

/* Named constants for Chart: '<S3>/Stavovy automat' */
#define IN_Fault                       ((uint8_T)1U)
#define IN_Init1B                      ((uint8_T)1U)
#define IN_InitA                       ((uint8_T)2U)
#define IN_Initialization              ((uint8_T)2U)
#define IN_NO_ACTIVE_CHILD             ((uint8_T)0U)
#define IN_Ready                       ((uint8_T)3U)
#define IN_Running                     ((uint8_T)4U)
#define IN_Service                     ((uint8_T)5U)
#define IN_Starting                    ((uint8_T)1U)
#define IN_Starting_state              ((uint8_T)6U)
#define IN_Starting_timer              ((uint8_T)2U)
#define IN_Stopping                    ((uint8_T)7U)

/* Block signals and states (default storage) */
DW rtDW;

/* Real-time model */
static RT_MODEL rtM_;
RT_MODEL *const rtM = &rtM_;
extern real_T rt_roundd_snf(real_T u);

/* Forward declaration for local functions */
static void check_phases(void);

/* Function for Chart: '<S3>/Stavovy automat' */
static void check_phases(void)
{
  /* Inport: '<Root>/V1' incorporates:
   *  Inport: '<Root>/V2'
   *  Inport: '<Root>/V3'
   */
  if ((get_V1() > 100) || (get_V3() > 100) || (get_V2() > 100)) {
    /* Outport: '<Root>/state' */
    v_set_state(99U);
  }

  /* End of Inport: '<Root>/V1' */
}

real_T rt_roundd_snf(real_T u)
{
  real_T y;
  if (fabs(u) < 4.503599627370496E+15) {
    if (u >= 0.5) {
      y = floor(u + 0.5);
    } else if (u > -0.5) {
      y = u * 0.0;
    } else {
      y = ceil(u - 0.5);
    }
  } else {
    y = u;
  }

  return y;
}

/* Model step function */
void automats_step(void)
{
  real_T rtb_Add3;
  real_T rtb_Switch1;
  real_T rtb_Switch2;
  int32_T rtb_Equal1_0;
  boolean_T rtb_Equal1;

  /* Chart: '<S3>/Stavovy automat' incorporates:
   *  Inport: '<Root>/faults'
   *  Inport: '<Root>/service'
   *  Inport: '<Root>/start'
   *  Inport: '<Root>/started'
   *  Inport: '<Root>/stop'
   *  Inport: '<Root>/stopped'
   *  Outport: '<Root>/state'
   */
  switch (rtDW.is_c2_automats) {
   case IN_Fault:
    if (get_service() == 1) {
      rtDW.is_c2_automats = IN_Service;

      /* Outport: '<Root>/faults_reset' */
      v_set_faults_reset(1U);

      /* Outport: '<Root>/state' */
      v_set_state(5U);

      /* Outport: '<Root>/dspace_reset' */
      v_set_dspace_reset(true);

      /* Outport: '<Root>/stop_set' */
      v_set_stop_set(false);
    }
    break;

   case IN_Initialization:
    if (rtDW.is_Initialization == IN_Init1B) {
      if ((rtDW.timer > 1000.0) && (get_faults() > 0)) {
        rtDW.is_Initialization = IN_NO_ACTIVE_CHILD;
        rtDW.is_c2_automats = IN_Fault;

        /* Outport: '<Root>/state' */
        v_set_state(99U);
      } else if (rtDW.timer > 1000.0) {
        rtDW.is_Initialization = IN_NO_ACTIVE_CHILD;
        rtDW.is_c2_automats = IN_Ready;

        /* Outport: '<Root>/state' */
        v_set_state(1U);

        /* Outport: '<Root>/faults_reset' */
        v_set_faults_reset(0U);

        /* Outport: '<Root>/dspace_reset' */
        v_set_dspace_reset(false);

        /* Outport: '<Root>/commands_set' */
        v_set_commands_set(false);
        check_phases();
      } else {
        rtDW.timer += 10.0;
      }
    } else {
      /* case IN_InitA: */
      rtDW.is_Initialization = IN_Init1B;
    }
    break;

   case IN_Ready:
    /* Outport: '<Root>/faults_reset' */
    v_set_faults_reset(0U);

    /* Outport: '<Root>/dspace_reset' */
    v_set_dspace_reset(false);
    if ((get_faults() == 1) || (v_get_state() == 99)) {
      rtDW.is_c2_automats = IN_Fault;
      v_set_state(99U);
    } else if (get_start() == 1) {
      /* Outport: '<Root>/start_on' */
      v_set_start_on(true);
      rtDW.is_c2_automats = IN_Starting_state;
      rtDW.is_Starting_state = IN_Starting;
      v_set_state(2U);
      rtDW.timer = 0.0;

      /* Outport: '<Root>/stop_set' */
      v_set_stop_set(false);
    } else {
      if (get_service() == 1) {
        rtDW.is_c2_automats = IN_Service;

        /* Outport: '<Root>/faults_reset' */
        v_set_faults_reset(1U);
        v_set_state(5U);

        /* Outport: '<Root>/dspace_reset' */
        v_set_dspace_reset(true);

        /* Outport: '<Root>/stop_set' */
        v_set_stop_set(false);
      }
    }
    break;

   case IN_Running:
    if (get_faults() > 0) {
      rtDW.is_c2_automats = IN_Fault;

      /* Outport: '<Root>/state' */
      v_set_state(99U);
    } else {
      if (get_stop() == 1) {
        rtDW.is_c2_automats = IN_Stopping;

        /* Outport: '<Root>/state' */
        v_set_state(4U);
      }
    }
    break;

   case IN_Service:
    /* Outport: '<Root>/faults_reset' */
    v_set_faults_reset(1U);

    /* Outport: '<Root>/dspace_reset' */
    v_set_dspace_reset(true);
    if ((get_faults() == 0) && (get_service() == 0)) {
      rtDW.is_c2_automats = IN_Ready;

      /* Outport: '<Root>/state' */
      v_set_state(1U);

      /* Outport: '<Root>/faults_reset' */
      v_set_faults_reset(0U);

      /* Outport: '<Root>/dspace_reset' */
      v_set_dspace_reset(false);

      /* Outport: '<Root>/commands_set' */
      v_set_commands_set(false);
      check_phases();
    } else if (get_service() == 0) {
      rtDW.is_c2_automats = IN_Fault;

      /* Outport: '<Root>/state' */
      v_set_state(99U);
    } else {
      /* Outport: '<Root>/commands_set' */
      v_set_commands_set(true);
    }
    break;

   case IN_Starting_state:
    if (rtDW.is_Starting_state == IN_Starting) {
      if (get_faults() == 1) {
        rtDW.is_Starting_state = IN_NO_ACTIVE_CHILD;
        rtDW.is_c2_automats = IN_Fault;

        /* Outport: '<Root>/state' */
        v_set_state(99U);
      } else {
        rtDW.is_Starting_state = IN_Starting_timer;
      }
    } else {
      /* case IN_Starting_timer: */
      if (get_started() == 1) {
        rtDW.is_Starting_state = IN_NO_ACTIVE_CHILD;
        rtDW.is_c2_automats = IN_Running;

        /* Outport: '<Root>/state' */
        v_set_state(3U);

        /* Outport: '<Root>/start_on' */
        v_set_start_on(false);
      } else if (rtDW.timer > 29990.0) {
        rtDW.is_Starting_state = IN_NO_ACTIVE_CHILD;
        rtDW.is_c2_automats = IN_Fault;

        /* Outport: '<Root>/state' */
        v_set_state(99U);
      } else {
        rtDW.timer += 10.0;
      }
    }
    break;

   default:
    /* case IN_Stopping: */
    if (get_faults() > 0) {
      rtDW.is_c2_automats = IN_Fault;

      /* Outport: '<Root>/state' */
      v_set_state(99U);
    } else {
      if (get_stopped() == 1) {
        /* Outport: '<Root>/stop_set' */
        v_set_stop_set(true);
        rtDW.is_c2_automats = IN_Ready;

        /* Outport: '<Root>/state' */
        v_set_state(1U);

        /* Outport: '<Root>/faults_reset' */
        v_set_faults_reset(0U);

        /* Outport: '<Root>/dspace_reset' */
        v_set_dspace_reset(false);

        /* Outport: '<Root>/commands_set' */
        v_set_commands_set(false);
        check_phases();
      }
    }
    break;
  }

  /* End of Chart: '<S3>/Stavovy automat' */

  /* RelationalOperator: '<S2>/Equal1' incorporates:
   *  Outport: '<Root>/state'
   */
  rtb_Equal1 = (v_get_state() == 4);

  /* Outputs for Atomic SubSystem: '<S2>/Regulator' */
  /* Sum: '<S4>/Add5' incorporates:
   *  Constant: '<S4>/Constant1'
   *  Memory: '<S4>/Memory2'
   */
  rtb_Switch2 = rtDW.Memory2_PreviousInput + 11.0;

  /* Switch: '<S4>/Switch3' incorporates:
   *  Constant: '<S4>/Constant7'
   *  Inport: '<Root>/rpm_req'
   *  RelationalOperator: '<S4>/Equal'
   */
  if (rtb_Equal1) {
    rtb_Equal1_0 = 500;
  } else {
    rtb_Equal1_0 = get_rpm_req();
  }

  /* End of Switch: '<S4>/Switch3' */

  /* Sum: '<S4>/Sum2' incorporates:
   *  Inport: '<Root>/rpm'
   */
  rtb_Switch1 = (real_T)rtb_Equal1_0 - get_rpm();

  /* Switch: '<S4>/Switch1' incorporates:
   *  Abs: '<S4>/Abs2'
   *  Constant: '<S4>/Constant3'
   *  Constant: '<S4>/Constant4'
   *  Logic: '<S2>/OR'
   *  Logic: '<S4>/OR'
   *  Outport: '<Root>/state'
   *  RelationalOperator: '<S2>/Equal'
   *  RelationalOperator: '<S4>/Relational Operator1'
   */
  if (((v_get_state() != 3) && (!rtb_Equal1)) || (!(30.0 < fabs(rtb_Switch1))))
  {
    rtb_Switch1 = 0.0;
  }

  /* End of Switch: '<S4>/Switch1' */

  /* Sum: '<S4>/Add3' incorporates:
   *  Memory: '<S4>/Memory1'
   */
  rtb_Add3 = rtb_Switch1 + rtDW.Memory1_PreviousInput;

  /* Sum: '<S4>/Add1' incorporates:
   *  Constant: '<S4>/Constant5'
   *  Constant: '<S4>/Constant9'
   *  Product: '<S4>/Product2'
   *  Product: '<S4>/Product4'
   */
  rtb_Switch1 = 0.0012 * rtb_Switch1 + rtb_Add3 * 0.00045;

  /* Switch: '<S5>/Switch2' incorporates:
   *  Constant: '<S4>/Constant1'
   *  Memory: '<S4>/Memory2'
   *  RelationalOperator: '<S5>/LowerRelop1'
   *  Sum: '<S4>/Add5'
   */
  if (!(rtb_Switch1 > rtDW.Memory2_PreviousInput + 11.0)) {
    /* Sum: '<S4>/Add6' */
    rtb_Switch2 = rtDW.Memory2_PreviousInput - 11.0;

    /* Switch: '<S5>/Switch' incorporates:
     *  RelationalOperator: '<S5>/UpperRelop'
     *  Sum: '<S4>/Add6'
     */
    if (!(rtb_Switch1 < rtDW.Memory2_PreviousInput - 11.0)) {
      rtb_Switch2 = rtb_Switch1;
    }

    /* End of Switch: '<S5>/Switch' */
  }

  /* End of Switch: '<S5>/Switch2' */

  /* Switch: '<S4>/Switch2' incorporates:
   *  Constant: '<S4>/Constant6'
   *  Constant: '<S4>/Constant8'
   *  RelationalOperator: '<S4>/Relational Operator2'
   */
  if (rtb_Switch2 < 135.0) {
    rtb_Switch2 = 135.0;
  }

  /* End of Switch: '<S4>/Switch2' */

  /* Switch: '<S4>/Switch4' incorporates:
   *  Constant: '<S4>/Constant10'
   *  RelationalOperator: '<S4>/Relational Operator3'
   */
  if (rtb_Switch2 > 3750.0) {
    rtb_Switch2 = 3750.0;
  }

  /* End of Switch: '<S4>/Switch4' */

  /* Update for Memory: '<S4>/Memory2' */
  rtDW.Memory2_PreviousInput = rtb_Switch2;

  /* Update for Memory: '<S4>/Memory1' */
  rtDW.Memory1_PreviousInput = rtb_Add3;

  /* Outport: '<Root>/rpm_sp' incorporates:
   *  Rounding: '<S4>/Round'
   */
  set_rpm_sp(rt_roundd_snf(rtb_Switch2));

  /* End of Outputs for SubSystem: '<S2>/Regulator' */
}

/* Model initialize function */
void automats_initialize(void)
{
  /* Chart: '<S3>/Stavovy automat' */
  rtDW.is_c2_automats = IN_Initialization;
  rtDW.is_Initialization = IN_InitA;
}

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