/****************************************************************************
Module
ButtonDB.c
Revision
1.0.1
Description
This implements the button debouncing state machine
Notes
History
/*----------------------------- 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 "ButtonDB.h"
#include "Projectile.h"
#include "Gameplay.h"
#include "DotStarService.h"
/*----------------------------- Module Defines ----------------------------*/
#define ms25 25
//assuming 1ms tick time
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this machine.They should be functions
relevant to the behavior of this state machine
*/
/*---------------------------- Module Variables ---------------------------*/
// everybody needs a state variable, you may need others as well.
// type of state variable should match htat of enum in header file
static ButtonState_t CurrentState;
static uint8_t LastButtonState;
// with the introduction of Gen2, we need a module level Priority var as well
static uint8_t MyPriority;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitButtonDB
Parameters
uint8_t : the priorty of this service
Returns
bool, false if error in initialization, true otherwise
Description
Saves away the priority, sets up the initial transition and initializes the
* button ports
Notes
Author
J. Edward Carryer, 10/23/11, 18:55
****************************************************************************/
bool InitButtonDB(uint8_t Priority)
{
ES_Event_t ThisEvent;
MyPriority = Priority;
// put us into the Initial PseudoState
CurrentState = InitButtonState;
// post the initial transition event
ThisEvent.EventType = ES_INIT;
Button_Tris = 1; //set rb8 to input;
CNPUBbits.CNPUB8 = 1; //turn on the pull up resistor 1 is when released, 0 when
pushed
if (ES_PostToService(MyPriority, ThisEvent) == true)
{
return true;
}
else
{
return false;
}
}
/****************************************************************************
Function
PostButtonService
Parameters
EF_Event_t ThisEvent , the event to post to the queue
Returns
boolean False if the Enqueue operation failed, True otherwise
Description
Posts an event to this state machine's queue
Notes
Author
C. Paullin
****************************************************************************/
bool PostButtonDB(ES_Event_t ThisEvent)
{
return ES_PostToService(MyPriority, ThisEvent);
}
/****************************************************************************
Function
RunButtonDB
Parameters
ES_Event_t : One of InitButtonState, Waiting, Falling_edge,
Rising_edge
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
debounces a button press
Notes
uses nested switch/case to implement the machine.
Author
C. Paullin
****************************************************************************/
ES_Event_t RunButtonDB(ES_Event_t ThisEvent)
{
ES_Event_t ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
switch (CurrentState)
{
case InitButtonState: // If current state is init Button State
{
if (ThisEvent.EventType == ES_INIT) // only respond to ES_Init
{
LastButtonState = Button_Port;
CurrentState = Waiting;
}
}
break;
case Waiting: // If current state is WAITING
{
switch (ThisEvent.EventType)
{
case ES_DB_RISING_EDGE: //If event is RISING EDGE
{ // Execute action function for state one : event one
ES_Timer_InitTimer(BUTTON_TIMER, ms25);
CurrentState = DB_RisingEdge; //Decide what the next state will be
}
break;
case ES_DB_FALLING_EDGE: //If event is RISING EDGE
{ // Execute action function for state one : event one
ES_Timer_InitTimer(BUTTON_TIMER, ms25);
CurrentState = DB_FallingEdge; //Decide what the next state will be
}
break;
default:
;
} // end switch on CurrentEvent
}
break;
case DB_RisingEdge:
{
switch (ThisEvent.EventType)
{
case ES_DB_FALLING_EDGE:
{
ES_Timer_StopTimer(BUTTON_TIMER);
CurrentState = Waiting;
}
break;
case ES_TIMEOUT:
{
CurrentState = Waiting; //don't do anything, only post on first
real falling edge
}
break;
default:
;
}
}
break;
case DB_FallingEdge:
{
switch (ThisEvent.EventType)
{
case ES_DB_RISING_EDGE:
{
ES_Timer_StopTimer(BUTTON_TIMER);
CurrentState = Waiting;
}
break;
case ES_TIMEOUT:
{
ES_Event_t Event2Post;
Event2Post.EventType = ES_BUTTON;
PostProjectile(Event2Post); //post event to projectile
service
PostGameplay(Event2Post);
PostDotStarService(Event2Post);
CurrentState = Waiting;
}
break;
default:
;
}
}
default:
;
}
return ReturnEvent;
}
/****************************************************************************
Function
CheckButton
Parameters
none
*
Returns
bool true if changed state, false if not
Description
checks if any change in button port
Notes
Author
C. Paullin
*/
bool CheckButton(void){
bool ReturnVal = false;
uint8_t CurrentButtonState;
CurrentButtonState= Button_Port;
ES_Event_t Event2Post;
if(CurrentButtonState!=LastButtonState){
ReturnVal = true;
LastButtonState = CurrentButtonState;
if(CurrentButtonState == Down){
Event2Post.EventType = ES_DB_FALLING_EDGE;
ES_PostToService(MyPriority, Event2Post);
}
if(CurrentButtonState == Up){
Event2Post.EventType = ES_DB_RISING_EDGE;
ES_PostToService(MyPriority, Event2Post);
}
}
return ReturnVal;
}
/***************************************************************************
private functions
***************************************************************************/