#include "ES_Configure.h"
#include "ES_Framework.h"
#include "AvatarService.h"
#include "PWM_PIC32.h"
#include "dbprintf.h"
/*----------------------------- Module Defines ----------------------------*/
#define AVATAR_MAX_TICK 5000
#define AVATAR_MIN_TICK 2000
#define AVATAR_SERVO_CH 1
#define ENV_MAX 200
/*---------------------------- 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 AvatarState_t CurrentState;
// global variables
uint16_t currentAvatarTick;
// with the introduction of Gen2, we need a module level Priority var as well
static uint8_t MyPriority;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitTemplateFSM
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 does any
other required initialization for this state machine
Notes
Author
J. Edward Carryer, 10/23/11, 18:55
****************************************************************************/
bool InitAvatarService(uint8_t Priority)
{
ES_Event_t ThisEvent;
MyPriority = Priority;
// put us into the Initial PseudoState
CurrentState = AVATAR_INIT;
// post the initial transition event
ThisEvent.EventType = ES_INIT;
if (ES_PostToService(MyPriority, ThisEvent) == true)
{
return true;
}
else
{
return false;
}
}
/****************************************************************************
Function
PostTemplateFSM
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
J. Edward Carryer, 10/23/11, 19:25
****************************************************************************/
bool PostAvatarService(ES_Event_t ThisEvent)
{
return ES_PostToService(MyPriority, ThisEvent);
}
/****************************************************************************
Function
RunTemplateFSM
Parameters
ES_Event_t : the event to process
Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
add your description here
Notes
uses nested switch/case to implement the machine.
Author
J. Edward Carryer, 01/15/12, 15:23
****************************************************************************/
ES_Event_t RunAvatarService(ES_Event_t ThisEvent)
{
ES_Event_t ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
switch (CurrentState)
{
case AVATAR_INIT: // If current state is initial Psedudo State
{
if (ThisEvent.EventType == ES_INIT) // only respond to ES_Init
{
CurrentState = AVATAR_IDLE;
DB_printf("Avatar Initialized.\n");
}
}
break;
case AVATAR_IDLE:
{
switch (ThisEvent.EventType)
{
case ES_START_BUTTON_PRESS:
{
// DB_printf("[Avatar Service] Responding to ES_START_BUTTON_PRESS\n");
CurrentState = AVATAR_PLAYING;
}
break;
default:
;
} // end switch on CurrentEvent
}
break;
case AVATAR_PLAYING:
{
switch (ThisEvent.EventType)
{
case ES_VOLUME_CHANGE:
{
// DB_printf("[Avatar Service] Responding to ES_VOLUME_CHANGE\n");
uint16_t vol = ThisEvent.EventParam;
uint16_t tick = VolumeToTick(vol);
currentAvatarTick = tick;
// DB_printf("Output Tick: %d\n", tick);
PWMOperate_SetPulseWidthOnChannel(tick, AVATAR_SERVO_CH);
}
break;
case ES_GAMEOVER_TIMEOUT:
case ES_NO_INPUT_TIMEOUT:
{
DB_printf("[Avatar Service] Responding to TIMEOUT\n");
CurrentState = AVATAR_IDLE;
currentAvatarTick = AVATAR_MAX_TICK;
PWMOperate_SetPulseWidthOnChannel(AVATAR_MAX_TICK, AVATAR_SERVO_CH);
}
break;
default:
;
} // end switch on CurrentEvent
}
break;
// repeat state pattern as required for other states
default:
;
} // end switch on Current State
return ReturnEvent;
}
/***************************************************************************
private functions
***************************************************************************/
uint16_t VolumeToTick(uint16_t vol)
{
if (vol > ENV_MAX)
{
vol = ENV_MAX;
}
uint16_t span = AVATAR_MAX_TICK - AVATAR_MIN_TICK;
uint16_t scaledVol = (uint16_t)((uint32_t)vol * (uint32_t)span / (uint32_t)ENV_MAX);
uint16_t tick = AVATAR_MAX_TICK - scaledVol; // motor moves CCW with sound
// uint16_t tick = AVATAR_MIN_TICK + scaledVol;
return tick;
}