Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Module
ReloadStateMachine.c
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
// Basic includes for a program using the Events and Services Framework
#include "ES_Configure.h"
#include "ES_Framework.h"
/* 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 "ReloadStateMachine.h"
#include "ReloadIRCaptureModule.h"
#include "MyPWMLib.h"
#include "MasterSM.h"
Parameters
ES_Event_t: the event to process
Returns
ES_Event_t: an event to return
Description
add your description here
Notes
uses nested switch/case to implement the machine.
Author
J. Edward Carryer, 2/11/05, 10:45AM
****************************************************************************/
ES_Event_t RunReloadStateMachine(ES_Event_t CurrentEvent)
{
//printf("running reload state machine \r\n");
bool MakeTransition = false;/* are we making a state transition? */
ReloadState_t NextState = CurrentState;
ES_Event_t EntryEventKind = { ES_ENTRY, 0 }; // default to normal entry to new
state
ES_Event_t ReturnEvent = CurrentEvent; // assume we are not consuming
event
switch (CurrentState)
{
//Entry state is measuring period.
case EMIT_IR:
{
//if we enter, then we need to start pulsing IR
//if we exit, then we disable pulsing
ReturnEvent = CurrentEvent = DuringEmitIR(CurrentEvent);
if (CurrentEvent.EventType != ES_NO_EVENT)
{
switch (CurrentEvent.EventType)
{
//if we got an event from the break-beam service
case GOT_BALL:
{
// we are leaving reload state machine and going to shoot state machine
//let upper state machine know we got a ball!
//TODO: make sure we increment ball count in upper state machine!
ReturnEvent.EventType = READY_TO_NAV_TO_SHOOT;
IncrementNumBalls();
printf("Got ball event found! \r\n");
}
break;
case ES_TIMEOUT:
{
//if the reload timer timesout, we go back to measuring IR period.
if (CurrentEvent.EventParam == RELOAD_TIMER)
{
ReturnEvent.EventType = READY_TO_NAV_TO_SHOOT;
IncrementNumBalls();
printf("Got ball event found! \r\n");
}
}
break;
//if we are entering first offense, then move to waiting for ball.
// this ensures we go shoot instead of trying to reload again (as we have
a ball)
case FIRST_OFFENSE:
{
//we need to measure period again
NextState = WAITING_FOR_BALL;
MakeTransition = true; //mark that we are taking a transition
// the upper state machine should not care about this.
ReturnEvent.EventType = ES_NO_EVENT;
printf("Got first offense event! \r\n");
}
break;
case OFFENSE_STARTED:
{
//we need to measure period again
NextState = WAITING_FOR_BALL;
MakeTransition = true; //mark that we are taking a transition
// the upper state machine should not care about this.
ReturnEvent.EventType = ES_NO_EVENT;
printf("Got offense (not first while in reloading state machine.) event!
\r\n");
}
break;
case DEFENSE_STARTED:
{
//we need to measure period again
NextState = WAITING_FOR_BALL;
MakeTransition = true;
HeadedToDefense = true;
//mark that we are taking a transition
// the upper state machine should not care about this.
ReturnEvent.EventType = ES_NO_EVENT;
printf("Got offense (not first while in reloading state machine.) event!
\r\n");
}
break;
}
}
}
break;
case WAITING_FOR_BALL:
{
//if we are waiting for ball
// upon entering: start pulsing pwm.
ReturnEvent = CurrentEvent = DuringWaitingState(CurrentEvent);
if (CurrentEvent.EventType != ES_NO_EVENT)
{
switch (CurrentEvent.EventType)
{
//If our ball-break IR posts an event
case GOT_BALL:
{
//increment num balls
IncrementNumBalls();
// tell main state machine we got a ball.
if (HeadedToDefense)
{
ReturnEvent.EventType = DEFENSE_STARTED;
HeadedToDefense = false;
}
else
{
ReturnEvent.EventType = READY_TO_NAV_TO_SHOOT;
}
}
break;
//if our ball waiting times out, then we just go try to shoot
case ES_TIMEOUT:
{
IncrementNumBalls();
//make sure it's from the right timer.
if (CurrentEvent.EventParam == BALL_TIMER)
{
// tell main state machine we got a ball.
ReturnEvent.EventType = READY_TO_NAV_TO_SHOOT;
if (HeadedToDefense)
{
ReturnEvent.EventType = DEFENSE_STARTED;
HeadedToDefense = false;
}
else
{
ReturnEvent.EventType = READY_TO_NAV_TO_SHOOT;
}
}
}
case OFFENSE_STARTED:
{
HeadedToDefense = false;
}
break;
case DEFENSE_STARTED:
{
//we need to measure period again
HeadedToDefense = true;
//mark that we are taking a transition
// the upper state machine should not care about this.
ReturnEvent.EventType = ES_NO_EVENT;
printf("Got offense (not first while in reloading state machine.) event!
\r\n");
}
break;
}
}
}
break;
}
// If we are making a state transition
if (MakeTransition == true)
{
// Execute exit function for current state
CurrentEvent.EventType = ES_EXIT;
RunReloadStateMachine(CurrentEvent);
CurrentState = NextState; //Modify state variable
/****************************************************************************
Function
StartTemplateSM
Parameters
None
Returns
None
Description
Does any required initialization for this state machine
Notes
Author
J. Edward Carryer, 2/18/99, 10:38AM
****************************************************************************/
void StartReloadStateMachine(ES_Event_t CurrentEvent)
{
if (CurrentEvent.EventType != ES_ENTRY)
{
printf("Warnign, reload state ,machine was starting with a non-entry
event\r\n");
}
printf("reloading state machine started and emitting at half of %d us\r\n",
CurrentEvent.EventParam);
// to implement entry to a history state or directly to a substate
// you can modify the initialization of the CurrentState variable
// otherwise just start in the entry state every time the state machine
// is started
if (ES_ENTRY_HISTORY != CurrentEvent.EventType)
{
CurrentState = ENTRY_STATE;
}
// call the entry function (if any) for the ENTRY_STATE
RunReloadStateMachine(CurrentEvent);
}
/****************************************************************************
Function
QueryTemplateSM
Parameters
None
Returns
TemplateState_t The current state of the Template state machine
Description
returns the current state of the Template state machine
Notes
Author
J. Edward Carryer, 2/11/05, 10:38AM
****************************************************************************/
ReloadState_t QueryReloadStateMachine(void)
{
return CurrentState;
}
/***************************************************************************
private functions
***************************************************************************/
if (CurrentPeriod_US != 0)
{
My_PWM_SetFreq(2000000 / CurrentPeriod_US, 5);
My_PWM_SetDuty(50, PWM_CHANNEL);
printf("freq = %d\r\n", 2000000 / CurrentPeriod_US);
}
}
else if (Event.EventType == ES_EXIT)
{
My_PWM_SetDuty(0, PWM_CHANNEL);
ES_Timer_StopTimer(RELOAD_TIMER);
}
else
//nothing to do here.
{}
// return either Event, if you don't want to allow the lower level machine
// to remap the current event, or ReturnEvent if you do want to allow it.
return ReturnEvent;
}
return ReturnEvent;
}