/****************************************************************************
 Module
   LimitSwitchDebounce.c

 Revision
   1.0.1

 Description
   This is a limit switch debouncing service for ME218B project team 3 under
   the Gen2 Events and Services Framework.

 Notes

 History
 When           Who     What/Why
 -------------- ---     --------
 03/05/19       bibit   converted from template to project file
 01/16/12 09:58 jec     began conversion from TemplateFSM.c
****************************************************************************/

/*----------------------------- Include Files -----------------------------*/
/* include header files for this state machine as well as any machines at the
   next lower level in the hierarchy that are sub-machines to this machine
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "LimitSwitchDebounce.h"

// other modules
#include "GameplayHSM.h"

/*----------------------------- Module Defines ----------------------------*/
#define DebounceTime 200

/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this service.They should be functions
   relevant to the behavior of this service
*/

/*---------------------------- Module Variables ---------------------------*/
// with the introduction of Gen2, we need a module level Priority variable
static uint8_t  MyPriority;

static bool     FrontLeftDebouncing = false;
static bool     FrontRightDebouncing = false;
static bool     RearLeftDebouncing = false;
static bool     RearRightDebouncing = false;

/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
 Function
     InitLimitSwitchDebounce

 Parameters
     uint8_t : the priorty of this service

 Returns
     bool, false if error in initialization, true otherwise

 Description
     Saves away the priority, and does any
     other required initialization for this service
 Notes

 Author
     Bibit Bianchini, 3/05/2019
****************************************************************************/
bool InitLimitSwitchDebounce(uint8_t Priority)
{
  ES_Event_t ThisEvent;
  MyPriority = Priority;

  // post the initial transition event
  ThisEvent.EventType = ES_INIT;
  if (ES_PostToService(MyPriority, ThisEvent) == true)
  {
    return true;
  }
  else
  {
    return false;
  }
}

/****************************************************************************
 Function
     PostLimitSwitchDebounce

 Parameters
     EF_Event_t ThisEvent ,the event to post to the queue

 Returns
     bool false if the Enqueue operation failed, true otherwise

 Description
     Posts an event to this state machine's queue
 Notes

 Author
     Bibit Bianchini, 3/05/2019
****************************************************************************/
bool PostLimitSwitchDebounce(ES_Event_t ThisEvent)
{
  return ES_PostToService(MyPriority, ThisEvent);
}

/****************************************************************************
 Function
    RunLimitSwitchDebounce

 Parameters
   ES_Event_t : the event to process

 Returns
   ES_Event, ES_NO_EVENT if no error ES_ERROR otherwise

 Description
     Converts limit switch RAW events from Collision module into debounced
     events to send to Gameplay service.

 Notes

 Author
     Bibit Bianchini, 3/05/2019
****************************************************************************/
ES_Event_t RunLimitSwitchDebounce(ES_Event_t ThisEvent)
{
  ES_Event_t ReturnEvent;
  ReturnEvent.EventType = ES_NO_EVENT; // assume no errors

  switch (ThisEvent.EventType)
  {
    case FRONT_LIMIT_HIT_L_RAW:
    {
      if (FrontLeftDebouncing == false)
      {
        // post a limit switch hit event to Gameplay service
        ES_Event_t PostEvent;
        PostEvent.EventType = FRONT_LIMIT_HIT_L;
        PostGameplayMasterSM(PostEvent);

        // start a debouncing timer
        ES_Timer_InitTimer(FrontLeftDebounceTimer, DebounceTime);

        // set debouncing for this limit switch to true
        FrontLeftDebouncing = true;
      }
    }
    break;

    case FRONT_LIMIT_HIT_R_RAW:
    {
      if (FrontRightDebouncing == false)
      {
        // post a limit switch hit event to Gameplay service
        ES_Event_t PostEvent;
        PostEvent.EventType = FRONT_LIMIT_HIT_R;
        PostGameplayMasterSM(PostEvent);

        // start a debouncing timer
        ES_Timer_InitTimer(FrontRightDebounceTimer, DebounceTime);

        // set debouncing for this limit switch to true
        FrontRightDebouncing = true;
      }
    }
    break;

    case REAR_LIMIT_HIT_L_RAW:
    {
      if (RearLeftDebouncing == false)
      {
        // post a limit switch hit event to Gameplay service
        ES_Event_t PostEvent;
        PostEvent.EventType = REAR_LIMIT_HIT_L;
        PostGameplayMasterSM(PostEvent);

        // start a debouncing timer
        ES_Timer_InitTimer(RearLeftDebounceTimer, DebounceTime);

        // set debouncing for this limit switch to true
        RearLeftDebouncing = true;
      }
    }
    break;

    case REAR_LIMIT_HIT_R_RAW:
    {
      if (RearRightDebouncing == false)
      {
        // post a limit switch hit event to Gameplay service
        ES_Event_t PostEvent;
        PostEvent.EventType = REAR_LIMIT_HIT_R;
        PostGameplayMasterSM(PostEvent);

        // start a debouncing timer
        ES_Timer_InitTimer(RearRightDebounceTimer, DebounceTime);

        // set debouncing for this limit switch to true
        RearRightDebouncing = true;
      }
    }
    break;

    case ES_TIMEOUT:
    {
      switch (ThisEvent.EventParam)
      {
        case FrontLeftDebounceTimer:
        {
          // reset the debouncing flag for this limit switch
          FrontLeftDebouncing = false;
        }
        break;

        case FrontRightDebounceTimer:
        {
          // reset the debouncing flag for this limit switch
          FrontRightDebouncing = false;
        }
        break;

        case RearLeftDebounceTimer:
        {
          // reset the debouncing flag for this limit switch
          RearLeftDebouncing = false;
        }
        break;

        case RearRightDebounceTimer:
        {
          // reset the debouncing flag for this limit switch
          RearRightDebouncing = false;
        }
        break;
      }
    }
    break;
  }

  return ReturnEvent;
}

/***************************************************************************
 private functions
 ***************************************************************************/

/*------------------------------- Footnotes -------------------------------*/
/*------------------------------ End of file ------------------------------*/