/*
 * File: Controller.c
 *
 * Real-Time Workshop code generated for Simulink model Controller.
 *
 * Model version                        : 1.375
 * Real-Time Workshop file version      : 7.3  (R2009a)  15-Jan-2009
 * Real-Time Workshop file generated on : Mon Jan 11 12:01:09 2010
 * TLC version                          : 7.3 (Jan 18 2009)
 * C/C++ source code generated on       : Mon Jan 11 12:01:10 2010
 *
 * Target selection: motohawk_ert_rtw.tlc
 * Embedded hardware selection: Specified
 * Code generation objectives: Unspecified
 * Validation result: Not run
 */

#include "Controller.h"
#include "Controller_private.h"

uint8_T _sfEvent_Controller_;

/* Block signals (auto storage) */
BlockIO_Controller Controller_B;

/* Block states (auto storage) */
D_Work_Controller Controller_DWork;

/* Previous zero-crossings (trigger) states */
PrevZCSigStates_Controller Controller_PrevZCSigState;

/* Real-time model */
RT_MODEL_Controller Controller_M_;
RT_MODEL_Controller *Controller_M = &Controller_M_;

/*********************************************************************
 * Lookup Binary Search Utility BINARYSEARCH_real_T
 */
void BINARYSEARCH_real_T( uint32_T *piLeft, uint32_T *piRght, real_T u, const
  real_T *pData, uint32_T iHi)
{
  /* Find the location of current input value in the data table. */
  *piLeft = 0;
  *piRght = iHi;
  if (u <= pData[0] ) {
    /* Less than or equal to the smallest point in the table. */
    *piRght = 0;
  } else if (u >= pData[iHi] ) {
    /* Greater than or equal to the largest point in the table. */
    *piLeft = iHi;
  } else {
    uint32_T i;

    /* Do a binary search. */
    while (( *piRght - *piLeft ) > 1 ) {
      /* Get the average of the left and right indices using to Floor rounding. */
      i = (*piLeft + *piRght) >> 1;

      /* Move either the right index or the left index so that */
      /*  LeftDataPoint <= CurrentValue < RightDataPoint */
      if (u < pData[i] ) {
        *piRght = i;
      } else {
        *piLeft = i;
      }
    }
  }
}

/* end macro BINARYSEARCH_real_T
 *********************************************************************/

/*********************************************************************
 * Lookup Utility LookUp_real_T_real_T
 */
void LookUp_real_T_real_T( real_T *pY, const real_T *pYData, real_T u, const
  real_T *pUData, uint32_T iHi)
{
  uint32_T iLeft;
  uint32_T iRght;
  BINARYSEARCH_real_T( &(iLeft), &(iRght), u, pUData, iHi);

  {
    real_T lambda;
    if (pUData[iRght] > pUData[iLeft] ) {
      real_T num;
      real_T den;
      den = pUData[iRght];
      den = den - pUData[iLeft];
      num = u;
      num = num - pUData[iLeft];
      lambda = num / den;
    } else {
      lambda = 0;
    }

    {
      real_T yLeftCast;
      real_T yRghtCast;
      yLeftCast = pYData[iLeft];
      yRghtCast = pYData[iRght];
      if (lambda != 0) {
        yLeftCast += lambda * ( yRghtCast - yLeftCast );
      }

      (*pY) = yLeftCast;
    }
  }
}

/* end function LookUp_real_T_real_T
 *********************************************************************/

/*********************************************************************
 * Lookup 1D Utility LookUpEven_real_T_real_T
 */
void LookUpEven_real_T_real_T( real_T *pY, const real_T *pYData, real_T u,
  real_T valueLo, uint32_T iHi, real_T uSpacing)
{
  if (u <= valueLo ) {
    (*pY) = (*pYData);
  } else {
    real_T uAdjusted = u - valueLo;
    real_T tmpIdxLeft = uAdjusted / uSpacing;
    uint32_T iLeft = (uint32_T)tmpIdxLeft;
    if ((tmpIdxLeft >= 4294967296.0) || (iLeft >= iHi) ) {
      (*pY) = pYData[iHi];
    } else {
      {
        real_T lambda;

        {
          real_T num = (real_T)uAdjusted - ( iLeft * uSpacing );
          lambda = num / uSpacing;
        }

        {
          real_T yLeftCast;
          real_T yRghtCast;
          yLeftCast = pYData[iLeft];
          yRghtCast = pYData[((iLeft)+1)];
          if (lambda != 0) {
            yLeftCast += lambda * ( yRghtCast - yLeftCast );
          }

          (*pY) = yLeftCast;
        }
      }
    }
  }
}

/* end function LookUpEven_real_T_real_T
 *********************************************************************/

/* Model step function */
void Controller_step(void)
{
  /* Update absolute time for base rate */
  /* The "clockTick0" counts the number of times the code of this task has
   * been executed. The resolution of this integer timer is 1.0E-006, which is the step size
   * of the task. 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.
   */
  Controller_M->Timing.clockTick0++;
  if (!Controller_M->Timing.clockTick0)
    Controller_M->Timing.clockTickH0++;
}

/* Model initialize function */
void Controller_initialize(boolean_T firstTime)
{
  (void)firstTime;

  /* Registration code */

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

  /* initialize real-time model */
  (void) memset((void *)Controller_M,0,
                sizeof(RT_MODEL_Controller));

  /* block I/O */
  {
    Controller_B.s1_ReadCANMessage_o1 = 0.0;
    Controller_B.s1_ReadCANMessage_o2 = 0.0;
    Controller_B.s1_ReadCANMessage_o3 = 0.0;
    Controller_B.s1_ReadCANMessage3_o1 = 0.0;
    Controller_B.s1_ReadCANMessage3_o2 = 0.0;
    Controller_B.s1_ReadCANMessage3_o3 = 0.0;
    Controller_B.s1_secondsperhour = 0.0;
    Controller_B.s1_ReadCANMessage4 = 0.0;
    Controller_B.s1_ReadCANMessage5 = 0.0;
    Controller_B.s1_ReadCANMessage6 = 0.0;
    Controller_B.s1_ReadCANMessage2_o1 = 0.0;
    Controller_B.s1_ReadCANMessage2_o2 = 0.0;
    Controller_B.s1_ReadCANMessage2_o3 = 0.0;
    Controller_B.s1_ReadCANMessage1_o1 = 0.0;
    Controller_B.s1_ReadCANMessage1_o2 = 0.0;
    Controller_B.s1_ReadCANMessage1_o3 = 0.0;
    Controller_B.s1_Sum = 0.0;
    Controller_B.s1_Sum1 = 0.0;
    Controller_B.s1_DataTypeConversion8 = 0.0;
    Controller_B.s1_DataTypeConversion9 = 0.0;
    Controller_B.s1_DataTypeConversion10 = 0.0;
    Controller_B.s3_Product = 0.0;
    Controller_B.s13_DiscreteTransferFcn = 0.0;
    Controller_B.s18_Yk = 0.0;
    Controller_B.s11_Product4 = 0.0;
    Controller_B.s11_Foundation_Brake_Request = 0.0;
    Controller_B.s19_Vehicle_Ready = 0.0;
    Controller_B.s19_State = 0.0;
    Controller_B.s19_Battery_Connect_Command = 0.0;
    Controller_B.s19_Error = 0.0;
    Controller_B.s19_Motor_Enable = 0.0;
    Controller_B.s19_Gen_Enable = 0.0;
    Controller_B.s19_Forward_LED = 0.0;
    Controller_B.s19_Reverse_LED = 0.0;
    Controller_B.s19_Park_LED = 0.0;
    Controller_B.s19_Gear = 0.0;
    Controller_B.s12_charge_current = 0.0;
    Controller_B.s12_Desired_Engine_rpm = 0.0;
    Controller_B.s12_Enable_Generator = 0.0;
    Controller_B.s12_Current_Feedback_Enable = 0.0;
    Controller_B.s12_Engine_On = 0.0;
    Controller_B.s12_Throttle_Offset = 0.0;
    Controller_B.s12_Current_Track = 0.0;
    Controller_B.s12_Charge_State = 0.0;
  }

  /* states (dwork) */
  (void) memset((void *)&Controller_DWork, 0,
                sizeof(D_Work_Controller));
  Controller_DWork.s16_DelayInput2_DSTATE = 0.0;
  Controller_DWork.s14_UnitDelay_DSTATE = 0.0;
  Controller_DWork.s13_DiscreteTransferFcn_DSTATE = 0.0;
  Controller_DWork.s17_DelayInput2_DSTATE = 0.0;
  Controller_DWork.s15_UnitDelay_DSTATE = 0.0;
  Controller_DWork.s18_DelayInput2_DSTATE = 0.0;
  Controller_DWork.s22_DelayInput2_DSTATE = 0.0;
  Controller_DWork.s21_DelayInput2_DSTATE = 0.0;
  Controller_Foreground_Start();

  /* Start for function-call system: '<S2>/Background' */

  /* Start for trigger SubSystem: '<S38>/Post Shutdown two ticks before MPRD off' */

  /* Start for S-Function (fcncallgen): '<S43>/Function-Call Generator' incorporates:
   *  Start for SubSystem: '<S43>/Post Shutdown two ticks before MPRD off'
   */

  /* end of Start for SubSystem: '<S38>/Post Shutdown two ticks before MPRD off' */

  /* Start for trigger SubSystem: '<S38>/Save NV Vars one tick before MPRD off' */

  /* Start for S-Function (fcncallgen): '<S45>/Function-Call Generator' incorporates:
   *  Start for SubSystem: '<S45>/Save NV Vars one tick before MPRD off'
   */

  /* end of Start for SubSystem: '<S38>/Save NV Vars one tick before MPRD off' */

  /* Start for trigger SubSystem: '<S38>/Shutdown power on ECU565-128' */

  /* Start for S-Function (fcncallgen): '<S46>/Function-Call Generator' incorporates:
   *  Start for SubSystem: '<S46>/Shutdown power on ECU565-128'
   */

  /* end of Start for SubSystem: '<S38>/Shutdown power on ECU565-128' */

  /* S-Function Block: MPRD */
  {
    VolatileWork.mh_init_resource_MPRD = -1;
  }

  /* Start for trigger SubSystem: '<S41>/Clear' */

  /* Start for S-Function (fcncallgen): '<S51>/Function-Call Generator' incorporates:
   *  Start for SubSystem: '<S38>/motohawk_restore_nvmem'
   */

  /* end of Start for SubSystem: '<S41>/Clear' */

  /* Start for trigger SubSystem: '<S42>/Clear' */

  /* Start for S-Function (fcncallgen): '<S52>/Function-Call Generator' incorporates:
   *  Start for SubSystem: '<S38>/motohawk_store_nvmem'
   */

  /* end of Start for SubSystem: '<S42>/Clear' */
  Controller_PrevZCSigState.Startup_and_Shifting_Trig_ZCE = UNINITIALIZED_ZCSIG;
  Controller_PrevZCSigState.Charge_Controller_Trig_ZCE = UNINITIALIZED_ZCSIG;
  Controller_PrevZCSigState.ShutdownpoweronECU565128_Trig_ZCE = ZERO_ZCSIG;
  Controller_PrevZCSigState.SaveNVVarsonetickbeforeMPRDoff_Trig_ZCE = ZERO_ZCSIG;
  Controller_PrevZCSigState.ProcessorReboot_Trig_ZCE = ZERO_ZCSIG;
  Controller_PrevZCSigState.PostShutdowntwoticksbeforeMPRDoff_Trig_ZCE =
    ZERO_ZCSIG;
  Controller_PrevZCSigState.Clear_Trig_ZCE = ZERO_ZCSIG;
  Controller_PrevZCSigState.Clear_Trig_ZCE_e = ZERO_ZCSIG;

  /* Machine initializer */
  _sfEvent_Controller_ = CALL_EVENT;
  Controller_Foreground_Init();
}

/* Model terminate function */
void Controller_terminate(void)
{
  /* (no terminate code required) */
}

/* File trailer for Real-Time Workshop generated code.
 *
 * [EOF]
 */
