/****************************************************************************
 Module
   CollisionModule.c

 Revision
   1.0.1

 Description
   This is a Collision detection file for ME218B Lab 8 for Team 3.

 Notes

 History
 When           Who     What/Why
 -------------- ---     --------
 02/28/2019     bibit   converted from template service to project file
 01/15/12 11:12 jec     revisions for Gen2 framework
 11/07/11 11:26 jec     made the queue static
 10/30/11 17:59 jec     fixed references to CurrentEvent in RunTemplateSM()
 10/23/11 18:20 jec     began conversion from SMTemplate.c (02/20/07 rev)
****************************************************************************/
/*----------------------------- 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 "GameplayHSM.h"
#include "CollisionModule.h"
#include "PWM_Module.h"
#include "LimitSwitchDebounce.h"

#include "inc/hw_pwm.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_nvic.h"
#include "inc/hw_Timer.h"

#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/pwm.h"

/*----------------------------- Module Defines ----------------------------*/
#define FRONT_LEFT_SWITCH_HI BIT0HI
#define FRONT_RIGHT_SWITCH_HI BIT1HI
#define REAR_LEFT_SWITCH_HI BIT2HI
#define REAR_RIGHT_SWITCH_HI BIT3HI

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

/*---------------------------- Module Variables ---------------------------*/
static uint8_t  LastSwitchStates;

/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
 Function
     InitializeCollisionDetection

 Parameters
     none

 Returns
     none

 Description
     Initializes collision detection by sampling the limit switch line.

 Notes
     PE0 - GPIO input for front left limit switch
     PE1 - GPIO input for front right limit switch
     PE2 - GPIO input for rear left limit switch
     PE3 - GPIO input for rear right limit switch

 Author
     Bibit Bianchini, 2/28/2019
****************************************************************************/
void InitializeCollisionDetection(void)
{
  // Sample the limit switch port pin and use it to initialize history
  LastSwitchStates = HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + ALL_BITS));
}

/****************************************************************************
 Function
     LimitSwitchChecker

 Parameters
     none

 Returns
     bool - true if event(s) posted, false otherwise

 Description
     Event checker to determine if one or more limit switch has been hit.
     Results from this event checker are debounced in LimitSwitchDebounce
     service.

 Notes
     PE0 - GPIO input for front left limit switch
     PE1 - GPIO input for front right limit switch
     PE2 - GPIO input for rear left limit switch
     PE3 - GPIO input for rear right limit switch

 Author
     Bibit Bianchini, 2/28/2019
****************************************************************************/
bool LimitSwitchChecker(void)
{
  // initialize some helpful variables
  static ES_Event_t PostEvent;
  bool              ReturnVal = false;

  // grab the current switch line
  static uint8_t CurrentSwitchStates;
  CurrentSwitchStates = HWREG(GPIO_PORTE_BASE + (GPIO_O_DATA + ALL_BITS));

  // check if front left limit switch depressed (and wasn't before)
  if (((CurrentSwitchStates & FRONT_LEFT_SWITCH_HI) != 0) &&
      ((LastSwitchStates & FRONT_LEFT_SWITCH_HI) == 0))
  {
    // set return value to be true
    ReturnVal = true;

    // post that a limit switch was hit
    PostEvent.EventType = FRONT_LIMIT_HIT_L_RAW;
    PostLimitSwitchDebounce(PostEvent);
  }

  // check if front right limit switch depressed (and wasn't before)
  if (((CurrentSwitchStates & FRONT_RIGHT_SWITCH_HI) != 0) &&
      ((LastSwitchStates & FRONT_RIGHT_SWITCH_HI) == 0))
  {
    // set return value to be true
    ReturnVal = true;

    // post that a limit switch was hit
    PostEvent.EventType = FRONT_LIMIT_HIT_R_RAW;
    PostLimitSwitchDebounce(PostEvent);
  }

  // check if rear left limit switch depressed (and wasn't before)
  if (((CurrentSwitchStates & REAR_LEFT_SWITCH_HI) != 0) &&
      ((LastSwitchStates & REAR_LEFT_SWITCH_HI) == 0))
  {
    // set return value to be true
    ReturnVal = true;

    // post that a limit switch was hit
    PostEvent.EventType = REAR_LIMIT_HIT_L_RAW;
    PostLimitSwitchDebounce(PostEvent);
  }

  // check if rear right limit switch depressed (and wasn't before)
  if (((CurrentSwitchStates & REAR_RIGHT_SWITCH_HI) != 0) &&
      ((LastSwitchStates & REAR_RIGHT_SWITCH_HI) == 0))
  {
    // set return value to be true
    ReturnVal = true;

    // post that a limit switch was hit
    PostEvent.EventType = REAR_LIMIT_HIT_R_RAW;
    PostLimitSwitchDebounce(PostEvent);
  }

  // reset the last state of the switches
  LastSwitchStates = CurrentSwitchStates;

  // return return value
  return ReturnVal;
}

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

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