The spigots module was used to indicate the flow of water from the pump to the water gun.
Module Description:
Spigot.c uses pins PF1, PF2, PF3, and PF4 on the Tiva. In the game, players will rotate the spigot knobs on the game console to turn the water flow on. The Tiva reads in the encoder values from two different spigot knobs and then determines if the knobs have been turned far enough to turn the flow of water on. If a knob has been turned far enough, a blue indicator LED will turn on for that knob. The information gathered from this module determines if the players can then go on to pump water and shoot the IR gun.
Module Defines:
Read the hardware register values using:
ALL_BITS (0xff<<2)
Specify the number of counts from the encoder that will determine if the spigot is on: REVOLUTION 12
Module Functions:
None
Module Variables:
Create module level variables to store:
the current state in the spigot's state machine
encoder 1's last encoder state
encoder 2's last encoder state
counts from encoder 1
counts from encoder 2
spigot 1's last state
spigot 1's current state
spigot 2's last state
spigot 2's current state
bool for whether or the start button has been pressed
Public Functions:
1. Initi Spigot
Function:
bool InitSpigot(uint8_t Priority)
Description:
InitSpigot does all of the initializations of the port lines and data structures internal to the spigot.c module that are necessary to prepare the module to begin capturing the counts given off by the spigot encoders. Once this function has been run through once, then all of the other functions in the spigot.c module can be used.
Input:
uint8_t Priority: the priority number assigned to the spigot's queue
Output:
bool true or false, which signals whether the initial event to the spigot's state machine was successfully posted
Pseudocode:
Initialize port F on the Tiva.
Assign digital ports to pins PF1, PF2, PF3, and PF4.
Set the data directions on pins PF2 and PF3 to be inputs. These pins will be used to read the encoder counts to determine how far the spigots have been turned.
Set the data directions on pins PF1 and PF4 to be outputs. These pins will be used to control the indicator LEDs that let the players know whether or not water is flowing from the spigots.
Set the current state of the spigot state machine to InitialSpigot
Initialize both encoder counters to zero
Initialize the last state for each spigot to zero
Initialize the last state for each encoder to zero
Post an ES_INIT event to the spigot's state machine to signal that the initialization for the spigot module is complete
2. PostSpigot
Function:
bool PostSpigot(ES_Event ThisEvent)
Description:
This function posts an event to the spigot state machine's queue
Inputs:
ES_Event ThisEvent: the event to be posted to the spigot state machine's queue
Outputs:
bool true or false: false is returned if the post-to-queue operation failed; true is returned if the post-to-queue operation was successful
Pseudocode:
In the return statement, post the function's input parameter (ThisEvent) to the spigot's queue by using the module-level priority number.
3. Check SpigotEvents
Function:
bool CheckSpigotEvents(void)
Description:
This function tests for rising and falling edges from each encoder. For each spigot edge, the counter for that spigot is incremented or decremented. If the counter for a particular encoder reaches a certain value, an event is posted stating that either spigot 1 is on, spigot 2 is on, or both spigots are on.
Inputs:
None
Outputs:
bool true or false: false is returned if no event was posted; true is returned if an event was posted to a queue
Pseudocode:
Create a local last counter sum variable and initialize it to zero
If the start button was pressed
Create and initialize a current spigot variable to zero for each spigot
Get the current encoder input states by reading the input lines from PF2 and PF3
If encoder 1's signal is high
set encoder 1's current state to 1
If encoder 1's current state doesn't match its last state
increment the counter for encoder 1 by 1
set encoder 1's last state to its current state
End If
End If
If encoder 1's signal is low
set encoder 1's current state to 0
set encoder 1's last state to equal its current state
End If
If encoder 2's signal is high
set encoder 2's current state to 1
If encoder 2's current state doesn't match its last state,
increment the counter for encoder 2 by 1
set encoder 2's last state to equal its current state
End If
End If
If encoder 2's signal is low
set encoder's current state to 0
set encoder 2's last state to equal its current state
End If
If only spigot 1 is on
set spigot 1's current state to 1
If spigot 1's current state doesn't match its last state
post an ES_SPIGOT1_ON event to the spigot state machine
set spigot 1's last state to its current state
set the function's return value to true
End If
End If
If only spigot 2 is on
set spigot 2's current state to 1
If spigot 2's current state doesn't match its last state
post an ES_SPIGOT2_ON event to the spigot state machine
set spigot 2's last state to its current state
set the function's return value to true
End If
End If
If both spigots are on and weren't already on
post an ES_BOTH_SPIGOTS_ON event to the spigot, water reservoir, and water gun state machines
set the function's return value to true
End If
End If
Sum both spigot counter values and store that value
Return a bool true or false
4. RunSpigot
Function:
ES_Event RunSpigot(ES_Event ThisEvent)
Description:
RunSpigot implements the state machine for spigot
Inputs:
ES_Event ThisEvent: this event is passed into the function. It determines which part of the state machine should be running.
Outputs:
ES_Event ES_NO_EVENT: this event indicates that the spigot’s state machine queue is empty
Psuedocode:
Create a local variable to store the next state for the state machine
Set the next state for the state machine as the current state of the state machine
Read the current state of the state machine using a switch statement
If the current state case is InitialSpigot
If an ES_INIT event was received
turn off the spigot indicator LEDs by setting pins PF1 and PF4 low
set the next state as WaitingForGameStateSpigots
End If
Break out of the InitialSpigot block
If the current state case is WaitingForGameStartSpigots
If an ES_GAME_START event was received
set the start button pressed bool variable to true
set the next state as NoSpigotsOn
End If
Break out of the WaitingForGameStartSpigots block
If the current state case is NoSpigotsOn
If an ES_SPIGOT1_ON event was received
turn on spigot 1's indicator LED by setting pin PF1 high
set the next state as OneSpigotOn
End If
If an ES_SPIGOT2_ON event was received
turn on spigot 2's indicator LED by setting pin PF4 high
set the next state as OneSpigotOn
End If
Break out of the NoSpigotsOn block
If the current state case is OneSpigotOn
If an ES_BOTH_SPIGOTS_ON event was received
turn on both spigot indicator LEDs by setting PF1 and PF4 high
set the next state as BothSpigotsOn
End If
If an ES_GAME_RESET event was received
turn off both spigot indicator LEDs by setting PF1 and PF4 low
set all numerical variables (counters, etc) back to zero
set button pressed bool variable back to false
set the next state as WaitingForGameStartSpigots
End If
Break out of the OneSpigotOn block
If the current state case is BothSpigotsOn
If an ES_GAME_RESET event was received,
turn off both spigot indicator LEDs by setting PF1 and PF4 low
set all numerical variables (counters, etc) back to zero
set button pressed bool variable back to false
set the next state as WaitingForGameStartSpigots
End If
End of BothSpigotsOn block
End of switch statement
Set the current state of the state machine as the next state
Return an ES_NO_EVENT event to signal there are no events in the spigot's queue
End If
#ifndef SPIGOT_H
#define SPIGOT_H
// the common headers for C99 types
#include
#include
#include "ES_Configure.h"
#include "ES_Events.h"
#include "ES_Types.h" /* gets bool type for returns */
#define ALL_BITS (0xff<<2)
#define FULL_REVOLUTION 24
// typedefs for the states in the spigot state machine
// State definitions for use with the query function
typedef enum { InitialSpigot,
WaitingForGameStartSpigots,
NoSpigotsOn,
OneSpigotOn,
BothSpigotsOn} SpigotState_t ;
//Public function prototypes
bool InitSpigot (uint8_t Priority);
bool PostSpigot( ES_Event ThisEvent );
bool CheckSpigotEvents(void);
ES_Event RunSpigot(ES_Event ThisEvent);
#endif //SPIGOT_H
//#define SPIGOT_TESTING
/****************************************************************************
Module
Spigot.c
Revision
1.0.1
Description
-Uses pins PF0, PF1, PF2, and PF3 on the Tiva
-Users will rotate spigot knobs on the game console to turn the water flow on and off
-The Tiva reads in the encoder values from two different spigot knobs and then
determines if the knobs have been turned far enough to turn the water flow on and off.
The information gathered from this module determines if the players can pump water
and shoot the IR gun.
****************************************************************************/
//*----------------------------Include Files--------------------------------/
// this will pull in the symbolic definitions for events, which we will want
// to post in response to detecting events
#include "ES_Configure.h"
// this will get us the structure definition for events, which we will need
// in order to post events in response to detecting events
#include "ES_Events.h"
// if you want to use distribution lists then you need those function
// definitions too.
#include "ES_PostList.h"
// This include will pull in all of the headers from the service modules
// providing the prototypes for all of the post functions
#include "ES_ServiceHeaders.h"
// this test harness for the framework references the serial routines that
// are defined in ES_Port.c
#include "ES_Port.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "ES_ShortTimer.h"
#include "ES_Types.h" /* gets bool type for returns */
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
#include
#include
#include
#include "termio.h"
// include our own prototypes to insure consistency between header &
// actual functionsdefinition
#include "Spigot.h"
/*----------------------------- Module Defines ----------------------------*/
#define ALL_BITS (0xff<<2) //used for reading the hardware register values
#define REVOLUTION 12 //24 detents in full revolution of rotary encoder
/*---------------------------- 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 MyPriority;
//Nomenclature: Spigot 1 is the water gun spigot; spigot 2 is the pump spigot
// A refers to channel A; B refers to channel B
static SpigotState_t CurrentState;
static uint8_t lastEncoder1; //changed after code was working
static uint8_t lastEncoder2; //changed after code was working
static uint8_t counter1; //encoder counter for water gun spigot //changed after code was working
static uint8_t counter2; //encoder counter for pump spgiot //changed after code was working
static uint8_t lastSpigot1;
static uint8_t currentSpigot1;
static uint8_t lastSpigot2;
static uint8_t currentSpigot2;
static bool startButtonPressed = false;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitSpigot
Parameters
(uint8_t) priority number
Returns
(boolean) true if success, false if otherwise
Description
-Does all the initializations of the port lines and data structures internal
to the module that are necessary to prepare the module to begin capturing the
counts given off by the spigot encoders
-Complete this, and then all the other functions can then be used
****************************************************************************/
bool InitSpigot (uint8_t Priority){ //Takes a priority number, returns True.
//Create local variables
MyPriority = Priority; //Initialize the MyPriority variable with the passed in parameter.
ES_Event ThisEvent;
//Initialize the port line to receive encoder data (make pin an input)
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R5; //Enable GPIO Port F
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R5) != SYSCTL_PRGPIO_R5)
;
HWREG(GPIO_PORTF_BASE + GPIO_O_DEN) |= (GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4); //Assign digital port to Pins PF0,1,2,3,4
HWREG(GPIO_PORTF_BASE + GPIO_O_DIR) &= ~(GPIO_PIN_2 | GPIO_PIN_3); //Set data direction on Pins PF2,3 to be inputs (aka set bits to 0) (reads in encoder counts)
HWREG(GPIO_PORTF_BASE + GPIO_O_DIR) |= (GPIO_PIN_1 | GPIO_PIN_4); //Set data data direction on Pin PF1 and PF4 to be an output (turns on indicator LEDs)
//Sample port line and use it to initialize the last input state variables for each pin
//Nomenclature: Spigot 1 is the water gun spigot; spigot 2 is the pump spigot
// A refers to channel A; B refers to channel B
//Set CurrentState in state machine to InitSpigot
CurrentState = InitialSpigot;
puts("CurrentState set to InitialSpigot for spigot state machine\r");
//Set counters to 0
counter1 = 0;
counter2 = 0;
puts("Counters set\r");
lastSpigot1 = 0;
lastSpigot2 = 0;
//Initialize last encoder values to zero (both start low)
lastEncoder1 = 0;
lastEncoder2 = 0;
puts("Last encoders set\r");
//Post Event ES_Init to Spigot queue (this service)
ThisEvent.EventType = ES_INIT; //post the initial transition event (ES_INIT) if this service implements a state machine
PostSpigot(ThisEvent);
puts("sent es init\r\n");
return true;
}
//End of InitializeMorseElements
/****************************************************************************
Function
PostSpigot
Parameters
ES_Event ThisEvent ,the event to post to the queue
Returns
bool false if the queue operation failed, true otherwise
Description
Posts an event to this state machine's queue
Notes
****************************************************************************/
bool PostSpigot( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
/****************************************************************************
Function
CheckSpigotEvents
Parameters
none
Returns
boolean true if an event was posted
Description
-This function tests for rising and falling edges from each encoder.
For each spigot edge, the counter for that spigot is incremented or
decremented. If the counter reaches a certain value, an event is posted
stating that either both spigots are off, one spigot is on, or both spigots
are on
****************************************************************************/
bool CheckSpigotEvents(void){
//Create local variables
bool ReturnVal = false;
static uint8_t LastCounterSum = 0;
//Only check for spigot events if the start button has been pressed
if(startButtonPressed)
{
//More local variables
uint8_t CurrentInputSpig1A;
uint8_t CurrentInputSpig2A;
uint8_t currentEncoder1;
uint8_t currentEncoder2;
ES_Event ThisEvent;
currentSpigot1 = 0;
currentSpigot2 = 0;
//Get the current input states from the input lines
CurrentInputSpig1A = HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) & (GPIO_PIN_2); //ISOLATE PIN F2 and read it
CurrentInputSpig2A = HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) & (GPIO_PIN_3); //ISOLATE PIN F3 and read it
//Use the reads for each of the spigot encoder pins to determine how far each spigot has turned
//printf("Pin 0: %d\r\n", CurrentInputSpig1A);
//---------------------------------
//Test if Spigot1 is on
if(((CurrentInputSpig1A & BIT2HI) != 0)) //if 1A signal is high
{
//puts("here");
currentEncoder1 = 1; //1A is high...
if(currentEncoder1 != lastEncoder1) //...and the current and last
//ecoder states don't match
{
counter1++; //...then increment the counter for spigot1
//puts("1: INCREMENT\r\n");
lastEncoder1 = currentEncoder1; //set last encoder state to current encoder state for preparation for next loop through code
}
}
if(((CurrentInputSpig1A & BIT2HI) == 0)) //if 1A signal is low
{
currentEncoder1 = 0; //If 1A signal is low, don't alter the counter
lastEncoder1 = currentEncoder1; //set last encoder state to current encoder state for preparation for next loop through code
}
//---------------------------------
//Test if Spigot2 is on
if(((CurrentInputSpig2A & BIT3HI) != 0)) //if 2A signal is high
{
//puts("here");
currentEncoder2 = 1; //2A is high...
if(currentEncoder2 != lastEncoder2) //...and the current and last encoder states don't match
{
counter2++; //...then increment the counter for spigot2
//puts("2: INCREMENT\r\n");
lastEncoder2 = currentEncoder2; //set last encoder state to current encoder state for preparation for next loop through code
}
}
if(((CurrentInputSpig2A & BIT3HI) == 0)) //if 2A signal is low
{
currentEncoder2 = 0; //If 2A signal is low, don't alter the counter
lastEncoder2 = currentEncoder2; //set last encoder state to current encoder state for preparation for next loop through code
}
//---------------------------------
//printf("Counter 1: %d\r\n",counter1); //for debugging: comment out
//printf("\t\t\tCounter 2: %d\r\n",counter2); //for debugging: comment out
if((counter1 >= REVOLUTION) && (counter2 < REVOLUTION)) //check if spigot 1 is on
{
//turn on LED indicator so user knows to stop turning spigot1
//HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_1);
currentSpigot1 =1;
if(currentSpigot1 != lastSpigot1)
{
ThisEvent.EventType = ES_SPIGOT1_ON;
PostSpigot(ThisEvent);
lastSpigot1 = currentSpigot1;
ReturnVal = true;
}
}
if((counter2 >= REVOLUTION) && (counter1 < REVOLUTION)) //check if spigot 2 is on
{
//turn on LED indicator so user knows to stop turning spigot2
//HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_4);
currentSpigot2 =1;
if(currentSpigot2 != lastSpigot2)
{
ThisEvent.EventType = ES_SPIGOT2_ON;
PostSpigot(ThisEvent);
lastSpigot2 = currentSpigot2;
ReturnVal = true;
}
}
//Check to see if both of the spigots are completely on. If they are, send an event out to pump, spigot, and watergun state machines
//If Spigot1 counter value > REVOLUTION (aka 24 counts), then send an event that says spigot A is on
if((counter1 >= REVOLUTION) && (counter2 >= REVOLUTION) && ((counter1 + counter2)!= LastCounterSum)) //if both spigots are on
{
ThisEvent.EventType = ES_BOTH_SPIGOTS_ON;
//puts("Spigot Post");
PostSpigot(ThisEvent);
PostWaterReservoir(ThisEvent);
PostWaterGun(ThisEvent);
ReturnVal = true;
}
}
LastCounterSum = counter1 + counter2;
return ReturnVal;
} //End of CheckSpigotEvents
/****************************************************************************
Function
RunSpigot
Parameters
ES_Event ThisEvent ,the event to determine which part of the
switch statement to operate in
Returns
ES_Event ES_NO_EVENT
Description
Implements the state machine for Spigot
Note
The EventType field of ThisEvent will be one of: ES_INIT, ES_BOTH_SPIGOTS_ON, GAME_RESET
****************************************************************************/
ES_Event RunSpigot(ES_Event ThisEvent){
//Returns ES_NO_Event
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors ...THIS GOES AT BOTTOM OF FUNCTION??
//Local variables
SpigotState_t NextState;
//Set NextState to CurrentState
NextState = CurrentState;
//puts("Inside the run function\r\n"); //for debugging: comment out
//Based on the state of the CurrentState variable, choose one of the following blocks of code:
switch(CurrentState)
{
//------------------------------------
case InitialSpigot:
if(ThisEvent.EventType == ES_INIT)
{
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_1);
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_4);
//puts("in initial spigot going to no spigots on\r\n");
NextState = WaitingForGameStartSpigots;
//puts("Spigot state machine currently in InitialSpigot\r\n");
}
break; //end InitalSpigot block
//------------------------------------
case WaitingForGameStartSpigots:
if(ThisEvent.EventType == ES_GAME_START)
{
puts("start event found\r\n");
startButtonPressed = true; //this is used as guard condition on the //spigot event checker so you can't
//turn the spigots on before the start button has been pressed
NextState = NoSpigotsOn;
}
break; //end of WaitingForGameStartSpigot
//------------------------------------
case NoSpigotsOn:
//puts("Spigot state machines currently in NoSpigotsOn\r\n");
//turn off LED indicator so user knows they need to turn the spigots on
//puts("in no spigots on going to both spigots on\r\n");
//HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_1);
if(ThisEvent.EventType == ES_SPIGOT1_ON)
{
puts("Spigot 1 on posted\r\n");
NextState = OneSpigotOn;
//puts("Spigot state machine currently in BothSpigotsOn\r\n");
//turn on LED indicator #1 so user knows to stop turning spigot1
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_1);
}
if(ThisEvent.EventType == ES_SPIGOT2_ON)
{
NextState = OneSpigotOn;
puts("Spigot 2 on posted\r\n");
//turn on LED indicator #2 so user knows to stop turning spigot2
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_4);
}
break; //end NoSpigotsOn block
//------------------------------------
case OneSpigotOn:
if(ThisEvent.EventType == ES_BOTH_SPIGOTS_ON)
{
//turn on LED indication #2
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_1);
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_4);
NextState = BothSpigotsOn;
}
if(ThisEvent.EventType == ES_GAME_RESET)
{
//turn off LED indicator #1
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_1 | GPIO_PIN_4);
//set all counters and booleans back to their initial states
counter1 = 0;
counter2 = 0;
lastSpigot1 = 0;
lastSpigot2 = 0;
lastEncoder1 = 0;
lastEncoder2 = 0;
currentSpigot1 = 0;
currentSpigot2 = 0;
//set event checker guard back to false so it can't check for spigot events unless the start
//button has been pressed again
startButtonPressed = false;
NextState = WaitingForGameStartSpigots;
}
break;
//------------------------------------
case BothSpigotsOn:
if(ThisEvent.EventType == ES_GAME_RESET)
{;
//turn off LED indicator so user knows they need to turn the spigots on
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_1 | GPIO_PIN_4);
//set counters back to zero
counter1 = 0;
counter2 = 0;
lastSpigot1 = 0;
lastSpigot2 = 0;
lastEncoder1 = 0;
lastEncoder2 = 0;
currentSpigot1 = 0;
currentSpigot2 = 0;
//set event checker guard back to false so it can't check for spigot events unless the start
//button has been pressed again
startButtonPressed = false;
NextState = WaitingForGameStartSpigots;
}
break; //end BothSpigotsOn block
//------------------------------------
}
CurrentState = NextState;
//Return ES_NO_EVENT
return ReturnEvent; //this was defined at the top of the function
} //End of RunMorseElementsSM function
/*------------------------------ TEST HARNESS ------------------------------*/
#ifdef SPIGOT_TESTING
int main(void)
{
TERMIO_Init();
puts("This is the test harness for Spigot\r\n");
bool initialization;
initialization = InitSpigot(MyPriority);
bool test;
while(true)
{
//puts("here\r\n");
test = CheckSpigotEvents();
}
}
#endif /*MORSE_ELEMENTS_TESTING */
The water gun module coordinated the events relating to IR emitting and detection.
Module Description:
WaterGun.c uses pin A3 to control an IR LED and pin A4 to receive input from a phototransistor. When the program receives a trigger pressed event, it begins a PWM pulse of a known frequency. If the phototransistor receives this frequency, a flame hit event is generated.
Module Defines:
Read the hardware register values using: ALL_BITS (0xff<<2)
Phototransistor bit: RECBIT GPIO_PIN_4
Shortcut to read port A data: PORT_A_DATA HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS))
Module Functions:
static void UV_Start_Pulse(void);
static void UV_Stop_Pulse(void);
Module Variables:
Service Priority: static uint8_t MyPriority;
WaterGun state: static UVState_t WGState;
Public Functions:
1. InitWaterGun
Function:
bool InitWaterGun(uint8_t Priority)
Description:
InitWaterGun does all the initializations of the port lines and data structures internal to the WaterGun.c module that are necessary to prepare the module to begin sending and receiving IR. Once this function has been run once, then all of the other functions in the WaterGun.c module can be used.
Inputs:
uint8_t Priority: the priority number assigned to the water gun's queue
Outputs:
bool true or false, which signals whether the initial event to the water reservoir's state machine was successfully posted
Pseudocode:
Initialize PWM
Set 500 Hz frequency
Set current state to WG_Idle before spigot is turned on
Initialize the port line to monitor the button
Wait until port is ready
Set these bits as digital ins
Return True
2. PostWaterGun
Function:
bool PostWaterGun(ES_Event ThisEvent)
Description:
This function posts an event to the water gun state machine's queue
Inputs:
ES_Event ThisEvent: the event to be posted to the water gun state machine's queue
Outputs:
bool true or false: false is returned if the post-to-queue operation failed; true is returned if the post-to-queue operation was successful
Pseudocode:
In the return statement, post the function's input parameter (ThisEvent) to the water gun's queue by using the module-level priority number.
3. RunWaterReservoir
Function:
ES_Event RunWaterGun(ES_Event ThisEvent)
Description:
RunWaterGun Implements the state machine for the WaterGun.c module
Inputs:
ES_Event ThisEvent: this event is passed into the function. It determines which part of the state machine should be running
Outputs:
ES_Event ES_NO_EVENT: this event indicates that the water gun's state machine queue is empty
Pseudocode:
assume no errors
State machine based on current state
If WG_Ready2Shoot
If event is trigger pressed
Start Pulse
Decrement LED
Start Pulse Timer
Set current state to WG_Shooting
Else if event is spigot off
Set current state to WG_Idle
Else if event is timeout
Set current state to WG_Idle
If WG_Shooting
If event is pulse timer timeout
stop pulsing
set current state to WG_Ready2Shoot
else if event is shot detected
stop pulse
start motor
empty water reservoir
change current state to WG_Hit
Post Flame hit event
Else if event is spigot off
stop pulse
set current state to WG_Idle
Else if Event is reset or timer out
Set current state to WG_Idle
if WG_Hit
if event is pulse timer timeout
change state to WG_Ready2Shoot
Stop Motor
else if event is spigot off
set current state to WG_Idle
Stop Motor
Else if Event is reset or timer out
Set current state to WG_Idle
if state is WG_Idle
only respond to both spigots on
set current state to WG_Ready2Shoot
Return an ES_NO_EVENT event to signal there are no events in the water reservoir's queue
4. CheckPulse
Function:
bool CheckPulse(void)
Description:
Event Checker Function to determine if flame has been hit
Inputs:
None
Outputs:
Returns bool true if shot is detected
Pseudocode:
Get current state of phototransistor pin
If state is high and different from last state
Get current Time
If last 2 pulses less than 4 ms apart
Post event shot detected
Set last pulse time and state to current values
return true }
Set last pulse state to current value
return false
Private Module Functions
1. UV Start Pulse
Function:
void UV_Start_Pulse(void)
Description:
Starts the UV_Pulse for the gun
Inputs:
None
Outputs:
None
Pseudocode:
Set Duty Cycle on the IR Channel to 50% to start Pulse
2. UV Stop Pulse
Function:
void UV_Stop_Pulse(void)
Description:
Stops the UV_Pulse for the gun
Inputs:
None
Outputs:
None
Pseudocode:
Set Duty Cycle on the IR Channel to 0% to stop pulse
3. Start Motor
Function:
void Start_Motor(void)
Description:
Starts the motor for the gun
Inputs:
None
Outputs:
None
Pseudocode:
Set Duty Cycle on the motor channel to 50% to start motor
4. Stop Motor
Function:
void Stop_Motor(void)
Description:
Stops the motor for the gun
Inputs:
None
Outputs:
None
Pseudocode:
Set Duty Cycle on the motor channel to 0% to stop motor
#ifndef UV_Pulse_H
#define UV_Pulse_H
// Event Definitions
#include "ES_Configure.h" /* gets us event definitions */
#include "ES_Types.h" /* gets bool type for returns */
// typedefs for the states
// State definitions for use with the query function
typedef enum { WG_Shooting, WG_Ready2Shoot, WG_Hit, WG_Idle} UVState_t ;
// Public Function Prototypes
bool InitWaterGun(uint8_t Priority);
bool PostWaterGun(ES_Event ThisEvent);
bool CheckPulse(void);
bool CheckTrigPull(void);
ES_Event RunWaterGun( ES_Event ThisEvent );
#endif /* UV_Pulse_H */
//#define TEST
/****************************************************************************
Module
WaterGun.c
Revision
1.0.0
Description
UV Pulse (a service that implements a state machine)
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for the framework and this service
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "ES_ShortTimer.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
//#include "PWM8Tiva.h"
#include "PWMTiva.h"
#include "WaterGun.h"
#include "Flame.h"
#include "WaterReservoir.h"
/*----------------------------- Module Defines ----------------------------*/
// these times assume a 1.000mS/tick timing
#define ONE_SEC 976
#define HALF_SEC (ONE_SEC/2)
#define TWO_SEC (ONE_SEC*2)
#define FIVE_SEC (ONE_SEC*5)
#define ALL_BITS (0xff<<2)
#define RECBIT GPIO_PIN_4
#define TRIGBIT GPIO_PIN_3
#define PORT_A_DATA HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS))
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this service.They should be functions
relevant to the behavior of this service
*/
static void UV_Start_Pulse(void);
static void UV_Stop_Pulse(void);
/*---------------------------- Module Variables ---------------------------*/
// with the introduction of Gen2, we need a module level Priority variable
static uint8_t MyPriority;
static UVState_t WGState;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************/
bool InitWaterGun(uint8_t Priority){
MyPriority = Priority;
// Initialize PWM
PWM_TIVA_Init();
// Set 500 Hz frequency
PWM_TIVA_SetFreq(500, 1);
// Set current state to WG_Idle before spigot is turned on
WGState = WG_Idle;
//Initialize the port line to monitor the button
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R0;
//Wait until port is ready
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R0) != SYSCTL_PRGPIO_R0) ;
HWREG(GPIO_PORTA_BASE+GPIO_O_DEN) |= (RECBIT);
//Set these bits as digital ins
HWREG(GPIO_PORTA_BASE+GPIO_O_DIR) &= ~(RECBIT);
return true;
}
static void UV_Start_Pulse(void) {
// Set duty cycle to 50% to start pulse
PWM_TIVA_SetDuty(50, 2);
}
static void Start_Motor(void) {
PWM_TIVA_SetDuty(50, 3);
}
static void Stop_Motor(void) {
PWM_TIVA_SetDuty(0, 3);
}
static void UV_Stop_Pulse(void) {
// Set duty cycle to 0% to stop pulse
PWM_TIVA_SetDuty(0, 2);
}
bool PostWaterGun( ES_Event ThisEvent ) {
return ES_PostToService( MyPriority, ThisEvent);
}
bool CheckPulse(void) {
static uint8_t LastPulseState = 0;
static uint16_t LastPulseTime = 0;
//Get current state of phototransistor pin
uint8_t CurrentPulseState = (PORT_A_DATA & RECBIT);
// If state is high and different from last state
if ((CurrentPulseState > 0) && (CurrentPulseState != LastPulseState)) {
// Get current Time
uint16_t CurrentTime = ES_Timer_GetTime();
// If last 2 pulses less than 4 ms apart
if ((CurrentTime - LastPulseTime) < 4) {
//Post event shot detected
ES_Event ThisEvent;
ThisEvent.EventType = ES_FLAME_HIT;
PostWaterGun(ThisEvent);
PostFlame(ThisEvent);
printf("Shot Detected\r\n");
}
// Set last pulse time and state to current values
LastPulseTime = CurrentTime;
LastPulseState = CurrentPulseState;
return true;
}
// Set last pulse state to current value
LastPulseState = CurrentPulseState;
return false;
}
ES_Event RunWaterGun(ES_Event ThisEvent) {
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
// State machine based on current state
switch (WGState) {
// If WG_Ready2Shoot
case WG_Ready2Shoot :
// If event is trigger pressed
if ((ThisEvent.EventType == ES_TRIGGER_PRESSED) && (CheckWater())) {
printf("Firing\r\n");
// Start Pulse
UV_Start_Pulse();
// Decrement LED
DecrementLED();
// Start Pulse Timer
ES_Timer_InitTimer(PULSE_TIMER, 100);
// Set current state to WG_Shooting
WGState = WG_Shooting;
// Else if event is spigot off
} else if (ThisEvent.EventType == ES_SPIGOT_OFF) {
// Set current state to WG_Idle
WGState = WG_Idle;
}
else if ((ThisEvent.EventType == ES_GAME_RESET) || (ThisEvent.EventType == ES_GAME_TIMER_OUT)) {
// Set current state to WG_Idle
WGState = WG_Idle;
}
break;
// If WG_Shooting
case WG_Shooting :
// If event is pulse timer timeout
if (ThisEvent.EventType == ES_TIMEOUT) {
// stop pulsing
UV_Stop_Pulse();
// set current state to WG_Ready2Shoot
WGState = WG_Ready2Shoot;
// else if event is shot detected
} else if (ThisEvent.EventType == ES_FLAME_HIT) {
// stop pulse
UV_Stop_Pulse();
Start_Motor();
//empty water reservoir
EmptyReservoir();
// change current state to WG_Hit
WGState = WG_Hit;
//PostFlame(ThisEvent);
// Else if event is spigot off
} else if (ThisEvent.EventType == ES_SPIGOT_OFF) {
// stop pulse
UV_Stop_Pulse();
// set current state to WG_Idle
WGState = WG_Idle;
}
else if ((ThisEvent.EventType == ES_GAME_RESET) || (ThisEvent.EventType == ES_GAME_TIMER_OUT)) {
// Set current state to WG_Idle
WGState = WG_Idle;
}
break;
// if WG_Hit
case WG_Hit:
// if event is pulse timer timeout
if (ThisEvent.EventType == ES_TIMEOUT) {
// change state to WG_Ready2Shoot
WGState = WG_Ready2Shoot;
Stop_Motor();
// else if event is spigot off
} else if (ThisEvent.EventType == ES_SPIGOT_OFF) {
// set current state to WG_Idle
WGState = WG_Idle;
Stop_Motor();
}
else if ((ThisEvent.EventType == ES_GAME_RESET) || (ThisEvent.EventType == ES_GAME_TIMER_OUT)) {
// Set current state to WG_Idle
WGState = WG_Idle;
}
break;
// if state is WG_Idle
case WG_Idle:
// only respond to both spigots on
if (ThisEvent.EventType == ES_BOTH_SPIGOTS_ON) {
// set current state to WG_Ready2Shoot
WGState = WG_Ready2Shoot;
}
break;
}
return ReturnEvent;
}
#ifdef TEST
/* test Harness for testing this module */
#include "termio.h"
int main(void)
{
// Set the clock to run at 40MhZ using the PLL and 16MHz external crystal
SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN
| SYSCTL_XTAL_16MHZ);
// initialize the timer sub-system and console I/O
_HW_Timer_Init(ES_Timer_RATE_1mS);
TERMIO_Init();
//clrScrn();
InitWaterGun(1);
UV_Start_Pulse();
Motor_Start(); 0
for(;;)
;
return 0;
}
#endif
The trigger module was used to trigger the shooting of the IR emitter at the flame target receiver.
Module Description:
Trigger.c uses pin A3 to read the state of the water gun trigger. The module handles all the debouncing for the limit switch and sends the watergun module an event to indicate when the trigger has been pressed.
Module Defines:
Read the hardware register values using: ALL_BITS (0xff<<2)
Trigger bit: TRIGBIT GPIO_PIN_3
Shortcut to read port A data: PORT_A_DATA HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS))
Module Functions:
None
Module Variables:
Service Priority: static uint8_t MyPriority;
Trigger state: static TrigState_t TrigState;
Public Functions:
1. InitTrigger
Function:
bool InitTrigger(uint8_t Priority)
Description:
InitTrigger does all the initializations of the port lines and data structures internal to the Trigger.c module that are necessary to prepare the module to begin monitoring for trigger pulls. Once this function has been run once, then all of the other functions in the Trigger.c module can be used.
Inputs:
uint8_t Priority: the priority number assigned to the trigger's queue
Outputs:
bool true or false, which signals whether the initial event to the trigger's state machine was successfully posted
Pseudocode:
Initialize PWM
Initialize the port line to monitor the button
Wait until port is ready
Set trigger bit as digital in
Set Current Trigger State based on initial position
2. PostTrigger
Function:
bool PostTrigger(ES_Event ThisEvent)
Description:
This function posts an event to the trigger state machine's queue
Inputs:
ES_Event ThisEvent: the event to be posted to the water gun state machine's queue
Outputs:
bool true or false: false is returned if the post-to-queue operation failed; true is returned if the post-to-queue operation was successful
Pseudocode:
In the return statement, post the function's input parameter (ThisEvent) to the trigger's queue by using the module-level priority number.
3. RunTrigger
Function:
ES_Event RunTrigger(ES_Event ThisEvent)
Description:
RunTrigger Implements the state machine for the Trigger.c module
Inputs:
ES_Event ThisEvent: this event is passed into the function. It determines which part of the state machine should be running
Outputs:
ES_Event ES_NO_EVENT: this event indicates that the trigger's state machine queue is empty
Pseudocode:
Assume no errors
Switch state machine based on current state
If Trigger Pulled state
If Trigger has been released
Change state to debouncing
Start DB Timer
If Trigger Released state
If trigger is pressed
Change state to debouncing
Post Event to water gun queue
Start DB Timer
if Trigger debouncing state
If timeout event
If trigger is currently pulled, set state to pulled
else set it to released
return Return event
4. CheckTrigPull
Function:
bool CheckTrigPull(void)
Description:
Event Checker Function to determine if trigger has been pulled
Inputs:
None
Outputs:
Returns bool true if trigger has been pulled
Pseudocode:
Get current trigger state
If Current trigger state is high and different from last state
Post Trigger pressed event
Return true
Set last trigger state to current trigger state
Return false
5. CheckTrigRelease
Function:
bool CheckTrigRelease(void)
Description:
Event Checker Function to determine if trigger has been released
Inputs:
None
Outputs:
Returns bool true if trigger has been released
Pseudocode:
Get current trigger state
If Current trigger state is low and different from last state
Post Trigger pressed event
Return true
Set last trigger state to current trigger state
Return false
#ifndef TRIGGER_H
#define TRIGGER_H
// Event Definitions
#include "ES_Configure.h" /* gets us event definitions */
#include "ES_Types.h" /* gets bool type for returns */
// typedefs for the states
// State definitions for use with the query function
typedef enum { Trig_Pulled, Trig_Released, Trig_Debouncing} TrigState_t ;
// Public Function Prototypes
bool InitTrigger(uint8_t Priority);
bool PostTrigger(ES_Event ThisEvent);
bool CheckTrigPull(void);
bool CheckTrigRelease(void);
ES_Event RunTrigger( ES_Event ThisEvent );
#endif /* TRIGGER_H */
/****************************************************************************
Module
Trigger.c
Revision
1.0.0
Description
UV Pulse (a service that implements a state machine)
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for the framework and this service
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "ES_ShortTimer.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
//#include "PWM8Tiva.h"
#include "PWMTiva.h"
#include "WaterGun.h"
#include "Trigger.h"
/*----------------------------- Module Defines ----------------------------*/
// these times assume a 1.000mS/tick timing
#define ONE_SEC 976
#define HALF_SEC (ONE_SEC/2)
#define TWO_SEC (ONE_SEC*2)
#define FIVE_SEC (ONE_SEC*5)
#define ALL_BITS (0xff<<2)
#define RECBIT GPIO_PIN_4
#define TRIGBIT GPIO_PIN_3
#define PORT_A_DATA HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS))
/*---------------------------- 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 TrigState_t TrigState;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************/
bool InitTrigger(uint8_t Priority){
MyPriority = Priority;
// Initialize PWM
//PWM8_TIVA_Init();
PWM_TIVA_Init();
//Initialize the port line to monitor the button
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R0;
//Wait until port is ready
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R0) != SYSCTL_PRGPIO_R0) ;
HWREG(GPIO_PORTA_BASE+GPIO_O_DEN) |= (TRIGBIT);
//Set these bits as digital ins
HWREG(GPIO_PORTA_BASE+GPIO_O_DIR) &= ~(TRIGBIT);
if ((PORT_A_DATA & TRIGBIT) > 0) {
TrigState = Trig_Pulled;
} else {
TrigState = Trig_Released;
}
return true;
}
bool PostTrigger( ES_Event ThisEvent ) {
return ES_PostToService( MyPriority, ThisEvent);
}
bool CheckTrigPull(void) {
static uint8_t LastTriggerPin = 0;
//puts("Checking Trig\r\n");
// Get current trigger state
uint8_t CurrentTriggerPin = (PORT_A_DATA & TRIGBIT);
// If Current trigger state is high and different from last state
if ((CurrentTriggerPin > 0) && (CurrentTriggerPin != LastTriggerPin)) {
// Post Trigger pressed event
ES_Event ThisEvent;
ThisEvent.EventType = ES_TRIGGER_PRESSED;
//printf("TRIGGER PRESSED EVENT SENT \r\n");
PostTrigger(ThisEvent);
LastTriggerPin = CurrentTriggerPin;
// Return true
return true;
}
// Set last trigger state to current trigger state
LastTriggerPin = CurrentTriggerPin;
// Return false
return false;
}
bool CheckTrigRelease(void) {
static uint8_t LastTriggerPin = 0;
// Get current trigger state
uint8_t CurrentTriggerPin = (PORT_A_DATA & TRIGBIT);
// If Current trigger state is low and different from last state
if ((CurrentTriggerPin == 0) && (CurrentTriggerPin != LastTriggerPin)) {
// Post Trigger pressed event
ES_Event ThisEvent;
ThisEvent.EventType = ES_TRIGGER_RELEASED;
PostTrigger(ThisEvent);
LastTriggerPin = CurrentTriggerPin;
// Return true
return true;
}
// Set last trigger state to current trigger state
LastTriggerPin = CurrentTriggerPin;
// Return false
return false;
}
ES_Event RunTrigger(ES_Event ThisEvent) {
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
// State machine based on current staterff
switch (TrigState) {
// If Trigger Pulled state
case Trig_Pulled :
// If Trigger has been released
if (ThisEvent.EventType == ES_TRIGGER_RELEASED) {
// Change state to debouncing
TrigState = Trig_Debouncing;
// Start Timer
ES_Timer_InitTimer(TRIG_DB_TIMER, 10);
//printf("Trigger Released\r\n");
}
break;
// If Trigger Released state
case Trig_Released :
// If trigger is pressed
if (ThisEvent.EventType == ES_TRIGGER_PRESSED) {
//puts("trigger pressed\r\n");
// Change state to debouncing
TrigState = Trig_Debouncing;
// Post Event
PostWaterGun(ThisEvent);
//PostPump(ThisEvent);
//Start Timer
ES_Timer_InitTimer(TRIG_DB_TIMER,10);
//printf("Trigger Pulled\r\n");
}
break;
// if Trigger debouncing state
case Trig_Debouncing:
// If timeout
if (ThisEvent.EventType == ES_TIMEOUT) {
// If trigger is currently pulled, set state to pulled
if ((PORT_A_DATA & TRIGBIT) > 0) {
TrigState = Trig_Pulled;
// else set it to released
} else {
TrigState = Trig_Released;
}
}
break;
}
return ReturnEvent;
}
The servo module controlled the arm that held the flame and indicated the passage of time by responding to game-wide events.
Module Description
The servo state machine uses pins PB7 on the Tiva. Its movement is coordinated by game-wide timers and game win or game lose events. The game win event happens when all the lights on the flame are extinguished, and the game lose event occurs when the game timer expires. The servo uses PWM to determine its position, and the movement is executed with timers in a non-blocking way.
Module Defines:
The PWM channel for which the frequency will be set: #define PWM_6_7 3
The required frequency for the PWM channel #define REQ_FREQ 50
The final position the servo will go to when it is moving forward: #define FINAL_SERVO_POS 1950
The position increment for the servo moving forward: #define POS_INCREMENT 3
The position increment for the servo going in the reverse direction: #define REV_POS_INCREMENT 10
The servo start position: #define INITIAL_POS 2450
The position the servo will drop to when the players lose the game: #define SERVO_GAME_LOSE_POS 1930
The position in which the servo idles until the start button is pressed: #define SERVO_WAIT_FOR_START_POS 2250
One second in milliseconds: #define ONE_SEC 976
The amount of time the servo waits before advancing the next increment: #define SERVO_DELAY (ONE_SEC/4)
Module Functions:
None
Module Variables:
Create module level variables to store:
The priority number for the module
Current state of the servo’s state machine
Public Functions
1. InitServo
Function:
bool InitServo ( uint8_t Priority );
Description:
InitServo initializes the pin and port on the Tiva for a PWM output, initializes the PWM library, and places the servo state machine in its first state, ServoWaitingForStart.
Input:
uint8_t Priority: the priority number assigned to the servo’s queue
Output:
bool true, which signals whether the initial event to the servo’s state machine was successfully posted
Pseudocode:
Initialize the port for the servo as a PWM output
Initialize the PWM system, set frequency to 500Hz 1% resolution, 0% DC
Upon initialization, set the CurrentState to ServoWaitingForStart
End of InitFlame
2. PostServo
Function:
bool PostServo(ES_EVENT ThisEvent)
Description:
PostServo posts an event to the servo state machine's queue
Input:
ES_EVENT ThisEvent: the event to be posted to the servo state machine's queue
Output:
bool true or false: false is returned if the post-to-queue operation failed; true is returned if the post-to-queue operation was successful
Pseudocode:
In the return statement, post the function's input parameter (ThisEvent) to the servo’s queue by using the module-level priority number.
3. RunServo
Function:
ES_Event RunServo(ES_Event ThisEvent)
Description:
RunServo implements the state machine for the servo.
Input:
ES_Event ThisEvent: this event is passed into the function. It determines which part of the state machine should be running.
Output:
ES_Event ES_NO_EVENT: this event indicates that the servo's state machine queue is empty
Pseudocode:
RunServo state machine
Initialize local variable ReturnValue to ES_NO_EVENT
Declare local variable NextState
Set NextState to CurrentState
Declare local variables for servo position
Based on the state of the CurrentState variable choose one
of the following blocks of code:
Servo state is ServoWaitingForStart
If ThisEvent is ES_INIT
Place servo in initial position
Else if ThisEvent is ES_START_GAME
Advance servo
Start servo delay timer
End ServoWaitingForStart block
Servo state is ServoFWD
If this event is ES_TIMEOUT
Increment the servo slowly in non-blocking way
Else if ThisEvent is ES_GAME_TIMER_OUT
Send servo to game lose position
Set current position to previous return position
Remain in current state and wait for GAME_RESET event
Else if this event is ES_ALL_FLAME_OFF
Maintain servo in current position
Set current position to previous reverse position
Start servo delay timer
Set NextState to ServoReturn
Else if this event is ES_GAME_RESET
Start servo delay timer
Set NextState to ServoReturn
End ServoFWD block
Servo state is ServoReturn
If the event is ES_TIMEOUT
Return servo to initial position slowly in non-blocking manner
Set current state to waiting for start
Servo state is ServoReturnStart
If the event is ES_TIMEOUT
Return servo to start position
Set current state to ServoWaitingForStart
End ServoReturn block
End switch statement
Increment the servo forward position
Increment the servo reverse position
Set CurrentState to NextState
return ReturnValue
End ServoSM
#ifndef ServoSM_H
#define ServoSM_H
// Event Definitions
#include "ES_Configure.h" /* gets us event definitions */
#include "ES_Types.h" /* gets bool type for returns */
#include "ES_Events.h"
// typedefs for the states
typedef enum { ServoFWD, ServoReturn,
ServoWaitingForStart, ServoReturnStart } ServoState_t ;
// State definitions for use with the query function
// Function prototypes
bool InitServo ( uint8_t Priority );
bool PostServo ( ES_Event ThisEvent );
ES_Event RunServo ( ES_Event ThisEvent );
#endif // IOModuleTemplate_H
// the common headers for I/O, C99 types
#include
#include
#include
// the headers to access the GPIO subsystem
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
// the header to get the timing functions
#include "ES_Port.h"
#include "PWMTiva.h"
#include "ServoSM.h"
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_ShortTimer.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"
// Module defines
#define PWM_6_7 3
#define REQ_FREQ 50 // units in Hz
//#define SERVO_DELAY 65535
#define FINAL_SERVO_POS 1950
#define POS_INCREMENT 3
#define REV_POS_INCREMENT 10
#define INITIAL_POS 2450
#define SERVO_GAME_LOSE_POS 1930
#define SERVO_WAIT_FOR_START_POS 2250
#define ONE_SEC 976
#define SERVO_DELAY (ONE_SEC/4)
#define GAME_LOSE_DELAY (ONE_SEC*4)
// Module variables
static ServoState_t CurrentState;
static uint8_t MyPriority;
// Function prototypes
bool InitServo ( uint8_t Priority );
bool PostServo ( ES_Event ThisEvent );
ES_Event RunServo ( ES_Event ThisEvent );
// Initialize the port for the servo as a PWM output
bool InitServo ( uint8_t Priority )
{
//enable GPIO Port B/ Bit 1
HWREG (SYSCTL_RCGCGPIO) |= (SYSCTL_RCGCGPIO_R1);
//wait until the peripheral reports that its clock is ready
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R1) != SYSCTL_PRGPIO_R1);
//Initialize the MyPriority variable with the passed in parameter.
MyPriority = Priority;
//Initialize the PWM system, set frequency to 500Hz 1% resolution, 0% DC
PWM_TIVA_Init();
//Set the frequency for a PWM channel group
PWM_TIVA_SetFreq( REQ_FREQ, PWM_6_7);
//Upon initialization, set the CurrentState to ServoWaitingForStart
CurrentState = ServoWaitingForStart;
ES_Event ThisEvent;
ThisEvent.EventType = ES_INIT;
PostServo (ThisEvent);
return true;
} //End of InitFlame
//Set up the post function for Flame service that will be called by other functions
bool PostServo ( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
// RunServo state machine
ES_Event RunServo ( ES_Event ThisEvent )
{
//initialize local variable ReturnValue to ES_NO_EVENT
ES_Event ReturnValue;
ReturnValue.EventType = ES_NO_EVENT; // assume no errors
//Declare local variable NextState
ServoState_t NextState;
//Set NextState to CurrentState
NextState = CurrentState;
//Declare local variables for servo position
static uint16_t NewServoPos = INITIAL_POS;
static uint16_t NewServoReversePos;
//Based on the state of the CurrentState variable choose one
//of the following blocks of code:
switch (CurrentState){
// Servo state is ServoWaitingForStart
case ServoWaitingForStart :
// If ThisEvent is ES_INIT
if (ThisEvent.EventType == ES_INIT){
//Place servo in initial position
PWM_TIVA_SetPulseWidth( SERVO_WAIT_FOR_START_POS, 1);
ES_Timer_InitTimer(SERVO_TIMER, SERVO_DELAY);
NewServoReversePos = SERVO_WAIT_FOR_START_POS;
NextState = ServoReturnStart;
// Else if ThisEvent is ES_START_GAME
} else if (ThisEvent.EventType == ES_GAME_START){
//Advance servo
PWM_TIVA_SetPulseWidth( INITIAL_POS, 1);
NewServoPos = INITIAL_POS;
//Start servo delay timer
ES_Timer_InitTimer(SERVO_TIMER, SERVO_DELAY);
NextState = ServoFWD;
} break; //End ServoWaitingForStart block
// Servo state is ServoFWD
case ServoFWD :
//If this event is ES_TIMEOUT
//Increment the servo slowly in non-blocking way
if ( ThisEvent.EventType == ES_TIMEOUT ){
PWM_TIVA_SetPulseWidth( NewServoPos, 1 );
if (NewServoPos >= FINAL_SERVO_POS){
ES_Timer_InitTimer(SERVO_TIMER, SERVO_DELAY);
}
// Else if ThisEvent is ES_GAME_TIMER_OUT
}else if (ThisEvent.EventType == ES_GAME_TIMER_OUT){
// Send servo to game lose position
PWM_TIVA_SetPulseWidth( SERVO_GAME_LOSE_POS, 1 );
// Set current position to previous position
NewServoReversePos = SERVO_GAME_LOSE_POS;
//Remain in current state and wait for GAME_RESET event
// Else if this event is ES_ALL_FLAME_OFF
} else if (ThisEvent.EventType == ES_ALL_FLAME_OFF){
// Maintain servo in current position
PWM_TIVA_SetPulseWidth( NewServoPos, 1 );
// Set current position to previous reverse position
NewServoReversePos = NewServoPos;
// Start servo delay timer
ES_Timer_InitTimer(SERVO_TIMER, SERVO_DELAY);
// Set NextState to ServoReturn
NextState = ServoReturn;
// Else if this event is ES_GAME_RESET
} else if (ThisEvent.EventType == ES_GAME_RESET){
// Start servo delay timer
ES_Timer_InitTimer(SERVO_TIMER, SERVO_DELAY);
// Set NextState to ServoReturn
NextState = ServoReturn;
}
break; //End ServoFWD block
// Servo state is ServoReturn
case ServoReturn :
// If the event is ES_TIMEOUT
// Return servo to initial position slowly in non-blocking manner
if ( ThisEvent.EventType == ES_TIMEOUT ){
PWM_TIVA_SetPulseWidth( NewServoReversePos, 1 );
if (NewServoReversePos <= SERVO_WAIT_FOR_START_POS){
ES_Timer_InitTimer(SERVO_TIMER, SERVO_DELAY);
} else {
// Make sure servo doesn't go past its limit
PWM_TIVA_SetPulseWidth( SERVO_WAIT_FOR_START_POS, 1 );
// Set current state to waiting for start
NextState = ServoWaitingForStart;
}
}
// Servo state is ServoReturnStart
case ServoReturnStart :
// If the event is ES_TIMEOUT
if ( ThisEvent.EventType == ES_TIMEOUT ){
// Return servo to start position
PWM_TIVA_SetPulseWidth( NewServoReversePos, 1 );
if (NewServoReversePos < INITIAL_POS){
ES_Timer_InitTimer(SERVO_TIMER, SERVO_DELAY);
} else if (NewServoReversePos >= INITIAL_POS){
// Set current state to ServoWaitingForStart
NextState = ServoWaitingForStart;
}
}
break; //End ServoReturn block
} // End switch statement
// Increment the servo forward position
// Increment the servo reverse position
// Set CurrentState to NextState
NewServoPos -= POS_INCREMENT;
NewServoReversePos += REV_POS_INCREMENT;
CurrentState = NextState;
// return ReturnValue
return ReturnValue;
} //End ServoSM
The water reservoir module indicaded when the water gun was ready to shoot and was controlled by the analog input to the pump.
Module Description:
WaterRservoir.c uses pins PA5, PA6, and PA7 on the Tiva to interface with a potentiometer connected to the pump lever, as well as a shift register that controls the numbers of blue water reservoir LEDs that are on. The number of LEDs in the water reservoir increments each time the potentiometer attached to the pump passes a threshold. The number of LEDs in the water reservoir decrements each time the player presses the trigger on the water gun.
Module Defines:
Read the hardware register values using: ALL_BITS (0xff<<2)
Maximum potentiometer reading: MAX_POT_READING 4095
Threshold for one reservoir LED on: ONE_LED 700
Threshold for two reservoir LEDs on: TWO_LED (ONE_LED*2)
Threshold for three reservoir LEDs on: THREE_LED (ONE_LED*3)
Threshold for four reservoir LEDs on: FOUR_LED (ONE_LED*4)
Threshold for five reservoir LEDs on: FIVE_LED (ONE_LED*5)
Threshold for six reservoir LEDs on: SIX_LED (ONE_LED*6)
Threshold for seven reservoir LEDs on: SEVEN_LED (ONE_LED*7)
Threshold for eight reservoir LEDs on: EIGHT_LED (ONE_LED*8)
Module Functions:
void turnOnLEDs (uint8_t LED_Data)
void ShiftClockPulse(void)
void RegisterClockPulse(void)
Module Variables:
Create module level variables to store:
priority number for the module
current state of the water reservoir's state machine
potentiometer's last value
potentiometer's current input state
threshold value that keeps track of how many reservoir LEDs should be lit
boolean that determines whether or not both of the spigots are on
Public Functions:
1. InitWaterReservoir
Function:
bool InitWaterReservoir(uint8_t Priority)
Description:
InitWaterReservoir does all the initializations of the port lines and data structures internal to the WaterReservoir.c module that are necessary to prepare the module to begin transforming the encoder data to the number of LEDs that should be on in the water reservoir. Once this function has been run once, then all of the other functions in the WaterReservoir.c module can be used.
Inputs:
uint8_t Priority: the priority number assigned to the water reservoir's queue
Outputs:
bool true or false, which signals whether the initial event to the water reservoir's state machine was successfully posted
Pseudocode:
Initialize port A on the Tiva
Assign digital ports to pins PA5, PA6, and PA7
Set the data directions on pins PA5, PA6, and PA7 to be outputs. These pins will be used to control the shift register that the water reservoir LEDs are attached to.
Set the current state of the water reservoir's state machine to InitialWaterReservoir
Initialize the potentiometer values
Initialize the module-level threshold variable that keeps track of how many reservoir LEDs are lit to zero
Post an ES_INIT event to the water reservoir's state machine to signal that the initialization for the water reservoir module is complete
2. PostWaterReservoir
Function:
bool PostWaterReservoir(ES_Event ThisEvent)
Description:
This function posts an event to the water reservoir state machine's queue
Inputs:
ES_Event ThisEvent: the event to be posted to the water reservoir state machine's queue
Outputs:
bool true or false: false is returned if the post-to-queue operation failed; true is returned if the post-to-queue operation was successful
Pseudocode:
In the return statement, post the function's input parameter (ThisEvent) to the water reservoir's queue by using the module-level priority number.
3. RunWaterReservoir
Function:
ES_Event RunWaterReservoir(ES_Event ThisEvent)
Description:
RunWaterReservoir Implements the state machine for the WaterReservoir.c module
Inputs:
ES_Event ThisEvent: this event is passed into the function. It determines which part of the state machine should be running
Outputs:
ES_Event ES_NO_EVENT: this event indicates that the water reservoir's state machine queue is empty
Pseudocode:
Create a local variable to store the next state for the state machine
Set the next state for the state machine as the current state of the state machine
Read the current state of the state machine using a switch statement
If the current state case is InitialWaterReservoir
turn off all water reservoir LEDs
set the threshold value indicating the number of active LEDs to zero
If an ES_INIT event was received,
set the next state as WaitingForGameStart
End If
Break out of the InitialWaterReservoir block
If the current state case is WaitingForGameStart
If an ES_GAME_START event was received
set the next state as WaitingForSpigots
End If
Break out of the WaitingForGameStart block
If the current state case is WaitingForSpigots
If an ES_BOTH_SPIGOTS_ON event was received
set module-level bool guard condition to say that both spigots on is true
initialize the pump timer to 100 ms
set the next state as WaitingForLever
End If
Break out of the WaitingForSpigots block
If the current state case is WaitingForLever
If an ES_GAME_RESET event was received
set module-level bool guard condition to say that both spigots on is false
turn off all water reservoir LEDs
set the threshold value indicating the number of active LEDs to zero
set the next state as WaitingForGameStart
Else If an ES_GAME_TIMER_OUT event was received
set module-level bool guard condition to say that both spigots on is false
turn off all water reservoir LEDs
set the threshold value indicating the number of active LEDs to zero
set the next state as WaitingForGameStart
Else If an ES_TIMEOUT event was received and the spigot guard condition is true
read the potentiometer and store the value
take the absolute value of the potentiometer reading and store it
If the number of active reservoir LEDs is less than 8
add the absolute value of the pot. reading to the LED threshold
End If
If threshold for 8 LEDs is hit
turn on all water reservoir LEDs using the shift register
Else If threshold for 7 LEDs is hit
turn on 7 water reservoir LEDs using the shift register
Else If threshold for 6 LEDs is hit
turn on 6 water reservoir LEDs using the shift register
Else If threshold for 5 LEDs is hit
turn on 5 water reservoir LEDs using the shift register
Else If threshold for 4 LEDs is hit
turn on 4 water reservoir LEDs using the shift register
Else If threshold for 3 LEDs is hit
turn on 3 water reservoir LEDs using the shift register
Else If threshold for 2 LEDs is hit
turn on 2 water reservoir LEDs using the shift register
Else If threshold for 1 LED is hit
turn on 1 water reservoir LED using the shift register
Else If threshold for 1 LED is not hit
turn off all water reservoir LEDs using the shift register
End If
End If
Break out of WaitingForLever block
End of switch statement
Set the current state of the state machine as the next state
Return an ES_NO_EVENT event to signal there are no events in the water reservoir's queue
4. DecrementLED
Function:
void DecrementLED(void)
Description:
DecrementLED deactivates one LED on the water reservoir
Inputs:
None
Outputs:
None
Pseudocode:
Remove one LED value from the module-level threshold variable that keeps track of how many reservoir LEDs are on
5. CheckWater
Function:
bool CheckWater(void)
Description:
Checks to see if any water reservoir LEDs are on
Inputs:
None
Outputs:
Returns bool true if at least one water reservoir LED is on; returns bool false if no water reservoir LEDs are on
Pseudocode:
If one water reservoir LED is on
return true
Else
return false
End If
6. EmptyReservoir
Function:
void EmptyReservoir(void)
Description:
EmptyReservoir turns off all of the water reservoir LEDs
Inputs:
None
Outputs:
None
Pseudocode:
Set the module-level LED threshold value to zero
Private Module Functions
1. turnOnLEds
Function:
void turnOnLEDs(uint8_t LED_Data)
Description:
turnOnLEDs uses the shift register to turn on a specific number of water reservoir LEDs in accordance with how much the players have pumped the lever
Inputs:
uint8_t LED_Data: a hex value that specifies which LEDs to turn on using the shift register
Outputs:
None
Pseudocode:
Repeat 8 times:
If bit 7 of the input hex number is high
set the data line to the shift register high using pin PA5
Else
set the data line to the shift register low using pin PA5
End If
pulse the shift clock
shift the input hex number by one position
End
Pulse the register clock
2. ShiftClockPulse
Function:
void ShiftClockPulse(void)
Description:
Pulses the shift clock on the shift register
Inputs:
None
Outputs:
None
Pseudocode:
Trigger a shift clock HI by setting pin PA6 high
Trigger a shift clock LoW by setting pin PA6 low
3. RegisterClockPulse
Function:
void RegisterClockPulse(void)
Description:
Pulses the register clock on the shift register
Inputs:
None
Outputs:
None
Pseudocode:
Trigger a register clock HI by setting pin PA7 high
Trigger a register clock LOW by setting pin PA7 low
#ifndef WATER_RESERVOIR_H
#define WATER_RESERVOIR_H
// the common headers for C99 types
#include
#include
#include "ES_Configure.h"
#include "ES_Events.h"
#include "ES_Types.h" /* gets bool type for returns */
#define ALL_BITS (0xff<<2)
// typedefs for the states in the spigot state machine
// State definitions for use with the query function
typedef enum { InitialWaterReservoir,
WaitingForGameStart,
WaitingForSpigots,
WaitingForLever} WaterReservoirState_t ;
//Public function prototypes
bool InitWaterReservoir (uint8_t Priority);
bool PostWaterReservoir( ES_Event ThisEvent );
void DecrementLED(void);
bool CheckWater(void);
void EmptyReservoir(void);
//bool CheckWaterReservoirEvents(void);
ES_Event RunWaterReservoir(ES_Event ThisEvent);
#endif //WATER_RESERVOIR_H
//#define WATER_RESERVOIR_TESTING
/****************************************************************************
Module
WaterReservoir.c
Revision
1.0.1
Description
-Uses pins PA5, PA6, and PA7 on the Tiva to interface with a shift register that
controls the numbers of water reservoir LEDs that are on
-The number of LEDs in the water reservoir increment when the pump has passed
a threshold. The number of LEDs in the water reservoir decrement when the players
take a shot with the water gun.
****************************************************************************/
//*----------------------------Include Files--------------------------------/
// this will pull in the symbolic definitions for events, which we will want
// to post in response to detecting events
#include "ES_Configure.h"
// this will get us the structure definition for events, which we will need
// in order to post events in response to detecting events
#include "ES_Events.h"
// if you want to use distribution lists then you need those function
// definitions too.
#include "ES_PostList.h"
// This include will pull in all of the headers from the service modules
// providing the prototypes for all of the post functions
#include "ES_ServiceHeaders.h"
// this test harness for the framework references the serial routines that
// are defined in ES_Port.c
#include "ES_Port.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "ES_ShortTimer.h"
#include "ES_Types.h" /* gets bool type for returns */
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
#include
#include
#include
#include
#include "termio.h"
// include our own prototypes to insure consistency between header &
// actual functionsdefinition
#include "WaterReservoir.h"
//include analog stuff
#include "ADMulti.h"
/*----------------------------- Module Defines ----------------------------*/
#define ALL_BITS (0xff<<2) //used for reading the hardware register values
#define MAX_POT_READING 4095
#define ONE_LED 700
#define TWO_LED (ONE_LED*2)
#define THREE_LED (ONE_LED*3)
#define FOUR_LED (ONE_LED*4)
#define FIVE_LED (ONE_LED*5)
#define SIX_LED (ONE_LED*6)
#define SEVEN_LED (ONE_LED*7)
#define EIGHT_LED (ONE_LED*8)
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this service.They should be functions
relevant to the behavior of this service
*/
void turnOnLEDs (uint8_t LED_Data);
void ShiftClockPulse(void);
void RegisterClockPulse(void);
/*---------------------------- Module Variables ---------------------------*/
static uint8_t MyPriority;
//Nomenclature: Spigot 1 is the water gun spigot; spigot 2 is the pump spigot
// A refers to channel A; B refers to channel B
static WaterReservoirState_t CurrentState;
//static uint8_t numLEDs;
static uint32_t lastPotValue;
static uint32_t currentPotInputState[1];
static uint32_t isThreshold;
static bool spigotsOn = false;
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitWaterReservoir
Parameters
(uint8_t) priority number
Returns
(boolean) true if success, false if otherwise
Description
-Does all the initializations of the port lines and data structures internal
to the module that are necessary to prepare the module to begin transforming
the encoder data to the number of LEDs on in the water reservoir
-Complete this, and then all the other functions can then be used
****************************************************************************/
bool InitWaterReservoir (uint8_t Priority){ //Takes a priority number, returns True.
//Create local variables
MyPriority = Priority;
ES_Event ThisEvent;
puts("Beginning of init function\r\n");
//Initialize the port lines to send out data to the shift register (make pins outputs)
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R0; //Enable GPIO Port A
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R0) != SYSCTL_PRGPIO_R0)
;
HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); //Assign digital port to Pins PA5,6,7
HWREG(GPIO_PORTA_BASE + GPIO_O_DIR) |= (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); //Set data data direction on Pins PA5,6,7 to be an output
//Set CurrentState in state machine to InitialWaterReservoir
CurrentState = InitialWaterReservoir;
//Set counter for the number of LEDs that are on to be 0
//numLEDs = 0;
//Initialize the potentiometer values
ADC_MultiInit(1);
ADC_MultiRead(currentPotInputState);
lastPotValue = currentPotInputState[0];
currentPotInputState[0] = 0;
isThreshold = 0; //this keeps track of how many LEDs should be lit
//Post ES_INIT event to the water reservoir queue (this service) to create the intial transition event
ThisEvent.EventType = ES_INIT;
PostWaterReservoir(ThisEvent);
puts("ES_INIT posted \r\n");
return true;
}//end InitWaterReservoir
/****************************************************************************
Function
PostWaterReservoir
Parameters
ES_Event ThisEvent ,the event to post to the queue
Returns
bool false if the queue operation failed, true otherwise
Description
Posts an event to this state machine's queue
Notes
****************************************************************************/
bool PostWaterReservoir( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
} //end PostWaterReservoir
/****************************************************************************
Function
RunWaterReservoir
Parameters
ES_Event ThisEvent ,the event to determine which part of the
switch statement to operate in
Returns
ES_Event ES_NO_EVENT
Description
Implements the state machine for waterReservoir
****************************************************************************/
ES_Event RunWaterReservoir(ES_Event ThisEvent){
//Returns ES_NO_Event
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT;
//Local variables
WaterReservoirState_t NextState;
uint32_t newPotValue;
uint32_t potDifference = 0;
static uint8_t LED_Data = 0;
//Set NextState to CurrentState
NextState = CurrentState;
switch(CurrentState)
{
//--------------------------------------------
case InitialWaterReservoir:
//turn all LEDs off
turnOnLEDs(0);
isThreshold = 0;
if(ThisEvent.EventType == ES_INIT)
{
NextState = WaitingForGameStart;
}
break; //end InitialWaterReservoir block
//--------------------------------------------
case WaitingForGameStart:
if(ThisEvent.EventType == ES_GAME_START)
{
NextState = WaitingForSpigots;
}
break;
//--------------------------------------------
case WaitingForSpigots:
puts("I'm back in waiting for spigots\r\n");
if (ThisEvent.EventType == ES_BOTH_SPIGOTS_ON)
{
spigotsOn = true; //guard condition for turning leds on/off
puts("spigotsOn set to true\r\n");
ES_Timer_InitTimer(PUMP_TIMER, 100);
NextState = WaitingForLever;
}
break; //end WaitingForSpigots block
//--------------------------------------------
case WaitingForLever:
//puts("In waiting for lever state\r\n");
if(ThisEvent.EventType == ES_GAME_RESET)
{
spigotsOn = false; //guard condition for turning leds on/off
puts("spigotsOn set to false by restart\r\n");
//turn off all LEDs using the shift register
turnOnLEDs(0);
isThreshold = 0;
NextState = WaitingForGameStart;
}
else if(ThisEvent.EventType == ES_GAME_TIMER_OUT)
{
spigotsOn = false; //guard condition for turning leds on/off
puts("spigotsOn set to false by time out\r\n");
//turn off all LEDs using the shift register
turnOnLEDs(0);
isThreshold = 0;
NextState = WaitingForGameStart;
}
else if ((ThisEvent.EventType == ES_TIMEOUT) && (spigotsOn)) {
//sample pot by reading
//newPotValue = currentPotInputState[0];
ADC_MultiRead(currentPotInputState);
newPotValue = currentPotInputState[0];
//printf("newPotValue = %d\r\n", newPotValue);
//read absolute value of the difference
// Added 20 tic band to reduce changes due to noise
if(newPotValue > (lastPotValue + 20))
{
potDifference = newPotValue - lastPotValue;
}
else if(lastPotValue > (newPotValue + 20))
{
potDifference = lastPotValue - newPotValue;
}
//potDifference = abs(newPotValue - lastPotValue);
//variable += difference
if (isThreshold < EIGHT_LED) {
isThreshold += potDifference;
}
//printf("IsThreshVal: %d\r\n", isThreshold);
//if threshold met, next next LED on
if (isThreshold > EIGHT_LED)
{
//turn on eight LEDs with shift register
LED_Data = 0xff; //11111111
turnOnLEDs(LED_Data);
}
else if(isThreshold > SEVEN_LED)
{
//turn on seven LEDs with shift register
LED_Data = 0x7f; //01111111
turnOnLEDs(LED_Data);
}
else if(isThreshold > SIX_LED)
{
//turn on six LEDs with shift register
LED_Data = 0x3f; //00111111
turnOnLEDs(LED_Data);
}
else if(isThreshold > FIVE_LED)
{
//turn on five LEDs with shift register
LED_Data = 0x1f; //00011111
turnOnLEDs(LED_Data);
}
else if(isThreshold > FOUR_LED)
{
//turn on four LEDs with shift register
LED_Data = 0x0f; //00001111
turnOnLEDs(LED_Data);
}
else if(isThreshold > THREE_LED)
{
//turn on three LEDs with shift register
LED_Data = 0x07; //00000111
turnOnLEDs(LED_Data);
}
else if(isThreshold > TWO_LED)
{
//turn on two LEDs with shift register
LED_Data = 0x03; //00000011
turnOnLEDs(LED_Data);
}
else if(isThreshold > ONE_LED)
{
//turn on one LED with shift register
LED_Data = 0x01; //00000001
turnOnLEDs(LED_Data);
}
else if(isThreshold < ONE_LED)
{
LED_Data = 0;
turnOnLEDs(LED_Data);
}
else
{
//do nothing
}
lastPotValue = newPotValue;
ES_Timer_InitTimer(PUMP_TIMER, 100);
NextState = WaitingForLever;
}
break; //end WaitingForLever block
//--------------------------------------------
} //end of switch statement
CurrentState = NextState;
//Return ES_NO_EVENT
return ReturnEvent;
} //end of RunWaterReservoir state machine function
void DecrementLED(void)
{
isThreshold -= ONE_LED;
return;
}
bool CheckWater(void)
{
if (isThreshold > ONE_LED) {
return true;
} else{
return false;
}
}
void EmptyReservoir(void)
{
isThreshold = 0;
}
//***************************************************************
//Private helper functions!
//***************************************************************
//***************************************************************
// turnOnLEDs
// -Uses shift register to turn on the LEDs
//***************************************************************
void turnOnLEDs (uint8_t LED_Data)
{
//Write the bits to the shift register
uint8_t mask = BIT7HI;
for (int i = 0; i < 8; i++) {
if ((LED_Data & mask)!= 0) {
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS)) |= GPIO_PIN_5;
}else{
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~GPIO_PIN_5;
}
//Shift over one space
ShiftClockPulse();
LED_Data = LED_Data<<1;
}
//Transfer information to the circuit
RegisterClockPulse();
} //end of turnOnLEDs
//***************************************************************
// ShiftClockPulse
//***************************************************************
void ShiftClockPulse(void){
//Shift Clock Port: PA6
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS)) |= GPIO_PIN_6; //set high
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~GPIO_PIN_6; //set low
}
//***************************************************************
// RegisterClockPulse
//***************************************************************
void RegisterClockPulse(void){
//Register Clock Port: PA7
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS)) |= GPIO_PIN_7;
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~GPIO_PIN_7;
}
The EventCheckers.c file was used for testing the program by initiating events with keyboard strokes and for the Start Button module.
Module Description
The event checkers are part of the events and services framework and they are always checking for events that may occur by reading pin states from the Tiva or other inputs like keystrokes. Most services include them in the module except the two that helped debug and control game-wide events: game progression by keyboard input, and the reset button.
Module Defines:
The input value when the reset button is pressed: #define RESET_INPUT_HI 1
Used to always access all 8 bits at a time: #define ALL_BITS (0xff<<2)
Module Functions:
1. Check4Keystroke
Function:
bool Check4Keystroke (void);
Description:
InitResetButton initializes the pin and port on the Tiva for an input, places the button state machine in its first state, Ready2Sample, and starts the debounce timer for a full game duration of 60 seconds.
Input:
none
Output:
bool true or false: false is returned if none of the keys pressed caused an event to post
Pseudocode:
Event checker used to move through the game with keyboard strokes
new key waiting?
if the key is 's' and the event is game start
post the event to servo, spigot, flame, and water reservoir
write event post notice to console
else if the key is 'r' and the event is game reset
post to servo, flame, spigot, watergun, and water reservoir
write event post notice to console
else if the key is 'o' and the event is the game timeout
post to servo, flame, and water gun
write event post notice to console
else if the key is 'h' and the event is flame hit
post to the flame service
write event post notice to console
else if the key is 'a' and the event is all flame off
post to servo service
write event post notice to console
End Check4Keystroke
2. CheckResetButton
Function:
bool CheckResetButton(void)
Description:
CheckResetButton posts an event to the button state machine's queue
Input:
none
Output:
bool true or false: false is returned if there was no event posted to the reset button module
Pseudocode:
Event checker for Start Button service
Set CurrentButtonState to state read from port pin
If the CurrentButtonState is different from the LastButtonState and it is HI
PostEvent ES_BUTTON_HI to Reset Button service for debouncing
Endif
Set LastButtonState to the CurrentButtonState
Return ReturnVal
End of CheckButtonEvents
Module Variables:
Create module level variables to store:
The last state of the reset button
Public Functions
none
#ifndef EventCheckers_H
#define EventCheckers_H
// the common headers for C99 types
#include
#include
#include "Flame.h"
#include "Spigot.h"
#include "WaterGun.h"
#include "Trigger.h"
#include "ResetButton.h"
// MUST PUT FUNCTION PROTOTYPES FOR EVENT CHECKERS HERE
bool Check4Keystroke(void);
bool CheckFlameEvents(void);
bool CheckSpigotEvents(void);
bool CheckResetButton(void);
#endif /* EventCheckers_H */
// this will pull in the symbolic definitions for events, which we will want
// to post in response to detecting events
#include "ES_Configure.h"
// this will get us the structure definition for events, which we will need
// in order to post events in response to detecting events
#include "ES_Events.h"
// if you want to use distribution lists then you need those function
// definitions too.
#include "ES_PostList.h"
// This include will pull in all of the headers from the service modules
// providing the prototypes for all of the post functions
#include "ES_ServiceHeaders.h"
// this test harness for the framework references the serial routines that
// are defined in ES_Port.c
#include "ES_Port.h"
// include our own prototypes to insure consistency between header &
// actual functionsdefinition
#include "EventCheckers.h"
//HEADER FILES FOR SERVICE EVENT CHECKERS - ALSO NEED FUNCTION PROTOTYPES IN h FILE
#include "Spigot.h"
#include "Flame.h"
//neeeded for GPIO reads
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"
#include "BITDEFS.H"
#define RESET_INPUT_HI 1
// always access all 8 bits at a time
#define ALL_BITS (0xff<<2)
static uint8_t LastButtonState;
// Event checker used to move through the game with keyboard strokes
bool Check4Keystroke(void)
{
if ( IsNewKeyReady() ) // new key waiting?
{
ES_Event ThisEvent;
ThisEvent.EventType = ES_NEW_KEY;
ThisEvent.EventParam = GetNewKey();
if ( ThisEvent.EventParam == 's'){
ES_Event ThisEvent;
ThisEvent.EventType = ES_GAME_START;
PostServo( ThisEvent );
PostSpigot( ThisEvent );
PostFlame( ThisEvent );
PostWaterReservoir( ThisEvent );
printf ("\r\n Posted ES_GAME_START \r\n");
} else if ( ThisEvent.EventParam == 'r') {
ES_Event ThisEvent;
ThisEvent.EventType = ES_GAME_RESET;
PostServo( ThisEvent );
PostFlame( ThisEvent );
PostSpigot( ThisEvent );
PostWaterGun(ThisEvent);
PostWaterReservoir( ThisEvent );
printf ("\r\n Posted ES_GAME_RESET \r\n");
} else if ( ThisEvent.EventParam == 'o') {
ES_Event ThisEvent;
ThisEvent.EventType = ES_GAME_TIMER_OUT;
PostServo( ThisEvent );
PostFlame( ThisEvent );
PostWaterGun(ThisEvent);
printf ("\r\n Posted ES_TIMER_OUT\r\n");
} else if ( ThisEvent.EventParam == 'h'){
ES_Event ThisEvent;
ThisEvent.EventType = ES_FLAME_HIT;
PostFlame( ThisEvent );
printf ("\r\n Posted ES_FLAME_HIT \r\n");
} else if ( ThisEvent.EventParam == 'a'){
ES_Event ThisEvent;
ThisEvent.EventType = ES_ALL_FLAME_OFF;
PostServo( ThisEvent );
printf ("\r\n Posted ES_ALL_FLAME_OFF \r\n");
} else
return true;
}
return false;
}
/***************************************************************************/
// Event checker for Start Button service
bool CheckResetButton (void)
{
bool ReturnVal = false;
uint8_t CurrentButtonState;
//Set CurrentButtonState to state read from port pin
CurrentButtonState = (HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS))) & BIT2HI;
//If the CurrentButtonState is different from the LastButtonState and it is HI
if ((CurrentButtonState != LastButtonState) &&
(CurrentButtonState > 0))
{
// PostEvent ES_BUTTON_HI to Reset Button service for debouncing
ES_Event ThisEvent;
ThisEvent.EventType = ES_BUTTON_HI;
//printf("BUTTON HI EVENT POSTED");
PostResetButton(ThisEvent);
ReturnVal = true;
} // Endif
//Set LastButtonState to the CurrentButtonState
LastButtonState = CurrentButtonState;
//Return ReturnVal
return ReturnVal;
} //End of CheckButtonEvents
The flame module indicated when the water gun incrememntally put out the fire and sent a game-wide win event if they were all put out before the game timer expired.
Module Description
This module uses pins PB0, PB1, PB2, and PB3 on the Tiva. When the phototransistor on the flame has been "hit" by the IR water gun, one red LED on the flame will turn off. If the players don't extinguish all of the red LEDs before the game timer ends, a blower fan will turn on to simulate a fire in San Francisco. If the players successfully extinguish all of the LEDs before the game timer ends, a green LED strip will light up, simulating grass growing back after the fire.
Module Defines:
Read the hardware register values using:
#define ALL_BITS (0xff<<2)
Module Functions:
None
Module Variables:
Create module level variables to store the priority, the current state of the flame's state machine, and the number of red LEDs that are active on the flame
Public Functions
1. InitFlame
Function:
bool InitFlame (uint8_t Priority)
Description:
InitFlame initializes all of the port lines and data structures internal to the flame.c module that are necessary to prepare the module to begin controlling the flame LEDs. Once this function has run, then all of the other functions in the flame.c module can be used.
Input:
uint8_t Priority: the priority number assigned to the flame's queue
Output:
bool true or false, which signals whether the initial event to the flame's state machine was successfully posted
Pseudocode:
Initialize port B on the Tiva as an output.
Assign digital ports to pins PB0, PB1, PB2, and PB3
Set the data directions on pins PB0, PB1, PB2, and PB3 to be outputs. These pins will be used to control the red flame LEDs
Initialize port D on the Tiva as an output.
Assign digital ports to pins PD0, PD1, and PD3
Set the data directions on pins PD0, PD1, and PD3 to be outputs. These pins will be used to control the fan and the green LED strip.
Set the initial state for the flame's state machine to be InitialFlame
Initialize the module-level counter variable to be 4, which means all 4 red LEDs on the flame are active
Initialize PD1 to high so the 5V high line is on
Initialize PD3 to low so the blower fan is off
Post an ES_INIT event to the flame queue to signal that the initialization for the module is complete.
2. PostFlame
Function:
bool PostFlame(ES_EVENT ThisEvent)
Description:
PostFlame posts an event to the flame state machine's queue
Input:
ES_EVENT ThisEvent: the event to be posted to the flame state machine's queue
Output:
bool true or false: false is returned if the post-to-queue operation failed; true is returned if the post-to-queue operation was successful
Pseudocode:
In the return statement, post the function's input parameter (ThisEvent) to the flame's queue by using the module-level priority number.
3. RunFlame
Function:
ES_Event RunFlame(ES_Event ThisEvent)
Description:
RunFlame implements the state machine for the flame.
Input:
ES_Event ThisEvent: this event is passed into the function. It determines which part of the state machine should be running.
Output:
ES_Event ES_NO_EVENT: this event indicates that the flame's state machine queue is empty
Pseudocode:
Create a local variable to store the next state for the state machine.
Set the next state for the state machine as the current state of the state machine.
Read the current state of the state machine using a switch statement.
If the current state case is InitialFlame
If an ES_INIT event was received
turn on all red LEDs on the flame
set the next state as WaitingForStart
End If
Break out of the InitialFlame block
If the current state case is WaitingForStart
If an ES_GAME_START event was received
set the next state as AllLEDsOn
End If
Break out of the WaitingForStart block
If the current state case is AllLEDsOn
If an ES_FLAME_HIT event was received
decrement the module-level counter variable by 1
turn off LED connected to pin PB0
set the next state as SubsetLEDs on
End If
If an ES_GAME_TIMER_OUT event was received
turn the fan on using pin PD3
set the next state as SameStateLEDs
End If
Break out of the AllLEDsOn state
If the current state case is SubsetLEDsOn
If an ES_FLAME_HIT event was received and at least one red flame LED is on
If three red flame LEDs are on
turn off the red flame LED connected to pin PB1
decrement the module-level counter variable by 1
set the next state to SubsetLEDsOn
Else If two red flame LEDs are on
turn off the red flame LED connected to PB2
decrement the module-level counter variable by 1
set the next state to SubsetLEDsOn
End If
Else If an ES_FLAME_HIT event was received an only one red flame LED is on
turn off the red flame LED connected to pin PB3
decrement by the module-level counter variable by 1
post an ES_ALL_FLAME_OFF event to the servo and reset button modules
turn on the external 5V HI line by setting pin PD0 high and pin PD1 low
set the next state to NoLEDsOn
End If
If an ES_GAME_TIMER_OUT event was received
turn the fan on using pin PD3
set the next state to SameStateLEDs
EndIf
Break out of the SubsetLEDsOn block
If the current state case is NoLEDsOn
If an ES_GAME_RESET event was received
turn all of the red flame LEDs on using pins PB0, PB1, PB2, and PB3
set the module-level counting variable back to 4
turn off the external 5V HI line by setting pin PD0 low and pin PD1 high
set the next state to WaitingForStart
End If
Break out of the NoLEDsOn block
If the current state case is SameStateLEDs
If an ES_GAME_RESET event was received
turn the fan off using pin PD3
turn all red flame LEDs on using pins PB0, PB1, PB2, and PB3
set the module-level counting variable back to 4
set the next state to WaitingForStart
End If
Break out of the SameStateLEDs block
End of the switch statement
Set the current state of the state machine as the next state
Return an ES_NO_EVENT event to signal there are no events in the flame's queue
#ifndef FLAME_H
#define FLAME_H
// the common headers for C99 types
#include
#include
#include "ES_Configure.h"
#include "ES_Events.h"
#include "ES_Types.h" /* gets bool type for returns */
#define ALL_BITS (0xff<<2)
// typedefs for the states in the spigot state machine
// State definitions for use with the query function
typedef enum { InitialFlame,
WaitingForStart,
SameStateLEDs,
AllLEDsOn,
SubsetLEDsOn,
NoLEDsOn} FlameState_t ;
//Public function prototypes
bool InitFlame (uint8_t Priority);
bool PostFlame( ES_Event ThisEvent );
bool CheckFlameEvents(void);
ES_Event RunFlame(ES_Event ThisEvent);
#endif //FLAME_H
//#define FLAME_TESTING
/****************************************************************************
Module
Flame.c
Revision
1.0.1
Description
-Uses pins PB0, PB1, PB2, and PB3 on Tiva
-When the phototransister has been "hit" by the water gun, one red LED on the
flame cutout will turn off. If the players don't extinguish all of the red LEDs
before the game timer ends, a blower fan will turn on to simulate fire in SF.
If the players successfully extinguish all of the LEDs, a celebration will start.
****************************************************************************/
//*----------------------------Include Files--------------------------------/
// this will pull in the symbolic definitions for events, which we will want
// to post in response to detecting events
#include "ES_Configure.h"
// this will get us the structure definition for events, which we will need
// in order to post events in response to detecting events
#include "ES_Events.h"
// if you want to use distribution lists then you need those function
// definitions too.
#include "ES_PostList.h"
// This include will pull in all of the headers from the service modules
// providing the prototypes for all of the post functions
#include "ES_ServiceHeaders.h"
// this test harness for the framework references the serial routines that
// are defined in ES_Port.c
#include "ES_Port.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "ES_ShortTimer.h"
#include "ES_Types.h" /* gets bool type for returns */
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
#include
#include
#include
#include "termio.h"
// include our own prototypes to insure consistency between header &
// actual functionsdefinition
#include "Flame.h"
/*----------------------------- Module Defines ----------------------------*/
#define ALL_BITS (0xff<<2) //used for reading the hardware register values
/*---------------------------- 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 MyPriority;
static FlameState_t CurrentState;
static uint8_t counter; //keeps track of how many LEDs are on
/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
Function
InitFlame
Parameters
(uint8_t) priority number
Returns
(boolean) true if success, false if otherwise
Description
-Does all the initializations of the port lines and data structures internal
to the module that are necessary to prepare the module to begin controlling the
flame LEDs
-Complete this, and then all the other functions can then be used
****************************************************************************/
bool InitFlame (uint8_t Priority){ //Takes a priority number, returns True.
//Create local variables
MyPriority = Priority; //Initialize the MyPriority variable with the passed in parameter
ES_Event ThisEvent;
//Initialize the Tiva port lines to send out a signal (make pins outputs)
//Port F (LEDs)
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R1; //Enable GPIO Port B
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R1) != SYSCTL_PRGPIO_R1)
;
HWREG(GPIO_PORTB_BASE + GPIO_O_DEN) |= (GPIO_PIN_0 |GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); //Assign digital port to Pins PB0,1,2,3
HWREG(GPIO_PORTB_BASE + GPIO_O_DIR) |= (GPIO_PIN_0 |GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); //Set data data direction on Pin PF1 to be an output (turn on LEDs)
//Port D (Fan)
HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R3; //Enable GPIO Port D
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R3) != SYSCTL_PRGPIO_R3)
;
HWREG(GPIO_PORTD_BASE + GPIO_O_DEN) |= (GPIO_PIN_3 | GPIO_PIN_0 | GPIO_PIN_1); //Assign digital port to Pins PD3
HWREG(GPIO_PORTD_BASE + GPIO_O_DIR) |= (GPIO_PIN_3 | GPIO_PIN_0 | GPIO_PIN_1); //Set data data direction on Pin PD3 to be an output (turn fan on/off)
//Set CurrentState in state machine to InitialFlame
CurrentState = InitialFlame;
//initialize counter to 4, which means all 4 LEDs are on
counter = 4;
//Set blower fan to off initially
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_3);
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_1 );
//Pose Event ES_INIT to Flame queue
ThisEvent.EventType = ES_INIT;
PostFlame(ThisEvent);
puts("Es init posted\r\n");
return true;
}
//End of InitializeMorseElements
/****************************************************************************
Function
PostFlame
Parameters
ES_Event ThisEvent ,the event to post to the queue
Returns
bool false if the queue operation failed, true otherwise
Description
Posts an event to this state machine's queue
Notes
****************************************************************************/
bool PostFlame( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
/****************************************************************************
Function
CheckFlameEvents
Parameters
none
Returns
boolean true if an event was posted
Description
-This function tests to see if the phototransistor has been "hit" by the
IR water gun. If it has, it decrements the number of red LEDs that are lit
on the flame. If the players don't extinguish all of the LEDs by the end of
the game, a blower fan will turn on to simulate a fire in SF. If the players
do successfully quench the flames, a celebration begins.
****************************************************************************/
bool CheckFlameEvents(void){
//Create local variables
bool ReturnVal = false;
//If the LED counter is 0, all of the LEDs have been extinguished and the players win
if(counter == 0)
{
//ES_Event ThisEvent;
//ThisEvent.EventType = ES_ALL_FLAME_OFF;
//Post this to a distribution list for every part of the game that has to react to a win event
//DIST_LIST_0(ThisEvent);
}
return ReturnVal;
} //End CheckFlameEvents
/****************************************************************************
Function
RunSpigot
Parameters
ES_Event ThisEvent ,the event to determine which part of the
switch statement to operate in
Returns
ES_Event ES_NO_EVENT
Description
Implements the state machine for Flame
Note
The EventType field of ThisEvent will be one of: ES_INIT, ES_GAME_RESET, ES_GAME_TIMER_OUT, ES_FLAME_HIT
****************************************************************************/
ES_Event RunFlame(ES_Event ThisEvent){
//Returns ES_NO_Event
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT;
//Local variables
FlameState_t NextState;
//Set NextState to CurrentState
NextState = CurrentState;
//puts("inside run\r\n");
switch(CurrentState)
{
//------------------------------
case InitialFlame:
if(ThisEvent.EventType == ES_INIT)
{
//puts("inside initialFlame\r\n");
//turn on all red LEDs on the flame
HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
NextState = WaitingForStart;
}
break; //end InitialFlame block
//-------------------------------
case WaitingForStart:
if(ThisEvent.EventType == ES_GAME_START)
{
//puts("inside WaitingForStart\r\n");
NextState = AllLEDsOn;
}
break; //end WaitingForStart block
//------------------------------
case AllLEDsOn:
//puts("inside AllLEDsOn\r\n");
//printf("Counter: %d\r\f", counter);
if(ThisEvent.EventType == ES_FLAME_HIT)
{
//If flame was hit, decrement counter and turn one LED off (PB0)
HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_0); //turn off first LED (PB0)
counter--; //counter changes from 4 to 3
//printf("Counter: %d\r\f", counter);
NextState = SubsetLEDsOn;
}
if(ThisEvent.EventType == ES_GAME_TIMER_OUT)
{
//start blower fan
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_3);
NextState = SameStateLEDs;
printf ("\r\n sent SM to SameStateLEDs FROM ALLLEDsOn\r\n");
}
break; //end AllLEDsOn block
//-------------------------------
case SubsetLEDsOn:
//puts("Inside SubsetLEDsOn\r\n");
if((ThisEvent.EventType == ES_FLAME_HIT) && (counter > 0)) //as long as more than one LED is lit, do this
{
//Turn a specific LED off based on the value of the counter
if(counter == 3)
{
HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_1); //turn off second LED (PB1)
counter--; //counter changes from 3 to 2
//printf("Counter: %d\r\f", counter); //prints 2
//Stay in this state
NextState = SubsetLEDsOn;
}
else if(counter == 2)
{
HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_2); //turn off third LED (PB2)
counter--; //counter changes from 2 to 1
//printf("Counter: %d\r\f", counter);
//Stay in this state?
NextState = SubsetLEDsOn;
}
//If there's only one LED on, the next time the flame is hit, send it to the NoLEDsOn state
else if((ThisEvent.EventType == ES_FLAME_HIT) && (counter == 1))
{
HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_3); //turn off fourth and final LED (PB3)
counter--; //counter changes from 1 to 0
//printf("Counter: %d\r\f", counter);
ThisEvent.EventType = ES_ALL_FLAME_OFF;
PostServo(ThisEvent);
PostResetButton(ThisEvent);
//turn ON external 5 HI line
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_0);
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_1);
printf("\r\n THE PD0 PIN WENT HI \r\n");
NextState = NoLEDsOn;
} //End if
}
if(ThisEvent.EventType == ES_GAME_TIMER_OUT)
{
//start blower fan
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_3);
NextState = SameStateLEDs;
printf ("\r\n sent SM to SameStateLEDs from SUBSET LEDS ON\r\n");
}
break; // end SubsetLEDsOn state
//-----------------------------------
case NoLEDsOn:
//puts("Inside NoLEDsOn\r\n");
if(ThisEvent.EventType == ES_GAME_RESET)
{
//turn all LEDs on
HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
//set counter back to 4
counter = 4;
//printf("Counter set back to: %d\r\f", counter);
//send state machine to AllLEDsOn state
//turn off external 5 HI line
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_0);
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_1);
NextState = WaitingForStart;
}
break; //end NoLEDsOn stateh
//-----------------------------------
case SameStateLEDs:
if(ThisEvent.EventType == ES_GAME_RESET)
{
//turn blower fan off
HWREG(GPIO_PORTD_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_3);
puts("Inside SameStateLEDs\r\n");
//turn all LEDs on
HWREG(GPIO_PORTB_BASE+(GPIO_O_DATA + ALL_BITS)) |= (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
//set counter back to 4
counter = 4;
//printf("Counter set back to: %d\r\f", counter);
//send state machine to AllLEDsOn state
NextState = WaitingForStart;
}
break; //end SameStateLEDs state
//-----------------------------------
}
CurrentState = NextState;
//Return ES_NO_EVENT
return ReturnEvent;
} //End of RunFlame function
A start button press was required after a game-wide reset event, and it started a new game. It was also used to control game-wide timers.
Module Description
The start/reset button uses pin PA2 on the Tiva. Its purpose is to initiate a new game. The state machines for all other modules are reset once the game timers expire or the game is won, and they are placed in a waiting for start state. The button progresses the state machines from this state for a new game to begin.
Module Defines:
A second assuming a 1.000mS/tick timing: #define ONE_SEC 976
The amount of time used during button debouncing: #define DEBOUNCE_TIME (ONE_SEC/30)
Input read when the button is pressed: #define INPUT_HIGH 1
The amount of time the players have to beat the game: #define GAME_TIME 45000
If the game is won, this timer is used before a reset event: #define WIN_TIME 15000
The full duration of a losing game before modules are reset: #define FULL_GAME_RESET_TIME 60000
Used to always access all 8 bits at a time: #define ALL_BITS (0xff<<2)
Module Functions:
None
Module Variables:
Create module level variables to store:
The priority number for the module
Current state of the reset button’s state machine
Public Functions
1. InitResetButton
Function:
bool InitResetButton ( uint8_t Priority );
Description:
InitResetButton initializes the pin and port on the Tiva for an input, places the button state machine in its first state, Ready2Sample, and starts the debounce timer for a full game duration of 60 seconds.
Input:
uint8_t Priority: the priority number assigned to the servo’s queue
Output:
bool true, which signals whether the initial event to the button’s state machine was successfully posted
Pseudocode:
Initialize the port and pin for the button
Set CurrentState to be Ready2Sample
Start a short timer
End of InitializeButton (return True)
2. PostResetButton
Function:
bool PostResetButton(ES_EVENT ThisEvent)
Description:
PostResetButton posts an event to the button state machine's queue
Input:
ES_EVENT ThisEvent: the event to be posted to the button state machine's queue
Output:
bool true or false: false is returned if the post-to-queue operation failed; true is returned if the post-to-queue operation was successful
Pseudocode:
In the return statement, post the function's input parameter (ThisEvent) to the button’s queue by using the module-level priority number.
3. RunResetButton
Function:
ES_Event RunResetButton(ES_Event ThisEvent)
Description:
RunResetButton implements the state machine for the servo.
Input:
ES_Event ThisEvent: this event is passed into the function. It determines which part of the state machine should be running.
Output:
ES_Event ES_NO_EVENT: this event indicates that the button’s state machine queue is empty
Pseudocode:
RunResetButton function (implements a state machine for debouncing timing)
Local var ReturnValue initialized to ES_NO_EVENT
Based on the CurrentState, choose one of the following blocks of code
If CurrentState is Debouncing
If EventType is ES_TIMEOUT & parameter is debounce timer number
Start the timer for a new game
Post reset event to all lists
Start reset timer for full game
Set CurrentState to Ready2Sample
If CurrentState is Ready2Sample
If EventType is ButtonUp
Start debounce timer
Set CurrentState to debouncing
End if
If CurrentState is GameStarted
If players lose the game (45 sec) - event type is ES_TIMEOUT
Set CurrentState to WaitingForResetTimer
Else if players win the game - event type is ES_ALL_FLAME_OFF
Start a timer for the win delay time
Change CurrentState to GameWin
If CurrentState is GameWin
If event type is ES_TIMEOUT and it's the GAME_TIMER
Post ES_GAME_RESET to all services
Change CurrentState to Ready2Sample
If CurrentState is WaitingForResetTimer
If the event type is ES_TIMEOUT and it is the reset timer
Post ES_GAME_RESET to all services
Change CurrentState to Ready2Sample
Return ES_NO_EVENT
End of RunResetButton
#ifndef ResetButton_H
#define ResetButton_H
// Event Definitions
#include "ES_Configure.h" /* gets us event definitions */
#include "ES_Types.h" /* gets bool type for returns */
#include "ES_Framework.h"
// typedefs for the states
// State definitions for use with the query function
typedef enum { Debouncing, Ready2Sample, GameStarted, GameWin, WaitingForResetTimer} ResetButtonState_t ;
// Public Function Prototypes
bool InitResetButton ( uint8_t Priority );
bool PostResetButton ( ES_Event ThisEvent );
ES_Event RunResetButton ( ES_Event ThisEvent );
#endif // ResetButton_H
//Reset Button Module
/*----------------------------- Include Files -----------------------------*/
/* include header files for the framework and this service*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_DeferRecall.h"
#include "ES_ShortTimer.h"
#include "EventCheckers.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h" // Define PART_TM4C123GH6PM in project
#include "driverlib/gpio.h"
#include "BITDEFS.H"
/*----------------------------- Module Defines ----------------------------*/
// these times assume a 1.000mS/tick timing
#define ONE_SEC 976
#define DEBOUNCE_TIME (ONE_SEC/30)
#define INPUT_HIGH 1
#define GAME_TIME 45000
#define WIN_TIME 15000
#define FULL_GAME_RESET_TIME 60000
// always access all 8 bits at a time
#define ALL_BITS (0xff<<2)
/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this service.They should be functions
relevant to the behavior of this service
*/
bool InitResetButton ( uint8_t Priority );
bool PostResetButton ( ES_Event ThisEvent );
ES_Event RunResetButton ( ES_Event ThisEvent );
/*---------------------------- Module Variables ---------------------------*/
// with the introduction of Gen2, we need a module level Priority variable
static uint8_t MyPriority;
static ResetButtonState_t CurrentState;
/*------------------------------ Module Code ------------------------------*/
//Button module (a service that implements a state machine)
// InitializeButton
// Takes a priority number, returns True
bool InitResetButton ( uint8_t Priority )
{
// Initialize the MyPriority variable with the passed in parameter
MyPriority = Priority;
// Initialize the port line to monitor the button
// Enable GPIO Port A/ Bit 0
HWREG (SYSCTL_RCGCGPIO) |= (SYSCTL_RCGCGPIO_R0);
// Wait until the peripheral reports that its clock is ready
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R0) != SYSCTL_PRGPIO_R0);
// Write to the DEN to assign digital functions to PA2
HWREG(GPIO_PORTA_BASE+GPIO_O_DEN) |= (GPIO_PIN_2);
// Initialize pin 2, 2 & 3 on Port A to be an inputs
HWREG(GPIO_PORTA_BASE+GPIO_O_DIR) &= ~(GPIO_PIN_2);
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA + ALL_BITS)) &= ~(GPIO_PIN_2);
// Set CurrentState to be Ready2Sample
CurrentState = Ready2Sample;
// Start debounce timer
ES_Timer_InitTimer(DEBOUNCE_TIMER, DEBOUNCE_TIME);
// End of InitializeButton (return True)
return true;
}
/***************************************************************************/
// Set the post function for Button that will be called by other functions
bool PostResetButton ( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
/***************************************************************************/
// RunResetButton (implements a 2-state state machine for debouncing timing)
ES_Event RunResetButton ( ES_Event ThisEvent )
{
// Local var ReturnValue initialized to ES_NO_EVENT
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
// Based on the CurrentState, choose one of the following blocks of code
switch (CurrentState) {
// If CurrentState is Debouncing
case Debouncing :
// If EventType is ES_TIMEOUT & parameter is debounce timer number
if ((ThisEvent.EventType == ES_TIMEOUT) &&
(ThisEvent.EventParam == DEBOUNCE_TIMER)){
// Start the timer for a new game
ES_Timer_InitTimer(GAME_TIMER, GAME_TIME);
ES_Event ThisEvent;
ThisEvent.EventType = ES_GAME_START;
// Post reset event to all lists
ES_PostAll (ThisEvent);
// Start reset timer for full game
ES_Timer_InitTimer(RESET_TIMER, FULL_GAME_RESET_TIME);
printf ("\r\n ES_GAME_START event posted to all lists\r\n");
// Set CurrentState to Ready2Sample
CurrentState = GameStarted;
}
break;
// If CurrentState is Ready2Sample
case Ready2Sample :
// If EventType is ButtonUp
if (ThisEvent.EventType == ES_BUTTON_HI){
// Start debounce timer
ES_Timer_InitTimer(DEBOUNCE_TIMER, DEBOUNCE_TIME);
// Set CurrentState to debouncing
CurrentState = Debouncing;
} // End if
break;
// If CurrentState is GameStarted
case GameStarted:
// If players lose the game (45 sec) - event type is ES_TIMEOUT
if ((ThisEvent.EventType == ES_TIMEOUT) &&
(ThisEvent.EventParam == GAME_TIMER)){
ES_Event ThisEvent;
ThisEvent.EventType = ES_GAME_TIMER_OUT;
ES_PostAll (ThisEvent);
// Set CurrentState to WaitingForResetTimer
CurrentState = WaitingForResetTimer;
}
// Else if players win the game - event type is ES_ALL_FLAME_OFF
else if (ThisEvent.EventType == ES_ALL_FLAME_OFF) {
// Start a timer for the win delay time
ES_Timer_InitTimer(GAME_TIMER, WIN_TIME);
// Change CurrentState to GameWin
CurrentState = GameWin;
}
break;
// If CurrentState is GameWin
case GameWin:
// If event type is ES_TIMEOUT and it's the GAME_TIMER
if ((ThisEvent.EventType == ES_TIMEOUT) &&
(ThisEvent.EventParam == GAME_TIMER)){
ES_Event ThisEvent;
ThisEvent.EventType = ES_GAME_RESET;
// Post ES_GAME_RESET to all services
ES_PostAll (ThisEvent);
// Change CurrentState to Ready2Sample
CurrentState = Ready2Sample;
}
break;
// If CurrentState is WaitingForResetTimer
case WaitingForResetTimer :
// If the event type is ES_TIMEOUT and it is the reset timer
if ((ThisEvent.EventType == ES_TIMEOUT) &&
(ThisEvent.EventParam == RESET_TIMER)){
ES_Event ThisEvent;
ThisEvent.EventType = ES_GAME_RESET;
// Post ES_GAME_RESET to all services
ES_PostAll (ThisEvent);
// Change CurrentState to Ready2Sample
CurrentState = Ready2Sample;
}
break;
}
// Return ES_NO_EVENT
return ReturnEvent;
} // End of RunResetButton
The ES_Configure file was used to configure all of the service modules, event checkers, and timers in the events and services framework.
/****************************************************************************
Module
ES_Configure.h
Description
This file contains macro definitions that are edited by the user to
adapt the Events and Services framework to a particular application.
Notes
History
When Who What/Why
-------------- --- --------
10/11/15 18:00 jec added new event type ES_SHORT_TIMEOUT
10/21/13 20:54 jec lots of added entries to bring the number of timers
and services up to 16 each
08/06/13 14:10 jec removed PostKeyFunc stuff since we are moving that
functionality out of the framework and putting it
explicitly into the event checking functions
01/15/12 10:03 jec started coding
*****************************************************************************/
#ifndef CONFIGURE_H
#define CONFIGURE_H
/****************************************************************************/
// The maximum number of services sets an upper bound on the number of
// services that the framework will handle. Reasonable values are 8 and 16
// corresponding to an 8-bit(uint8_t) and 16-bit(uint16_t) Ready variable size
#define MAX_NUM_SERVICES 16
/****************************************************************************/
// This macro determines that nuber of services that are *actually* used in
// a particular application. It will vary in value from 1 to MAX_NUM_SERVICES
#define NUM_SERVICES 7
/****************************************************************************/
// These are the definitions for Service 0, the lowest priority service.
// Every Events and Services application must have a Service 0. Further
// services are added in numeric sequence (1,2,3,...) with increasing
// priorities
// the header file with the public function prototypes
#define SERV_0_HEADER "WaterReservoir.h"
// the name of the Init function
#define SERV_0_INIT InitWaterReservoir
// the name of the run function
#define SERV_0_RUN RunWaterReservoir
// How big should this services Queue be?
#define SERV_0_QUEUE_SIZE 5
/****************************************************************************/
// The following sections are used to define the parameters for each of the
// services. You only need to fill out as many as the number of services
// defined by NUM_SERVICES
/****************************************************************************/
// These are the definitions for Service 1
#if NUM_SERVICES > 1
// the header file with the public function prototypes
#define SERV_1_HEADER "ServoSM.h"
// the name of the Init function
#define SERV_1_INIT InitServo
// the name of the run function
#define SERV_1_RUN RunServo
// How big should this services Queue be?
#define SERV_1_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 2
#if NUM_SERVICES > 2
// the header file with the public function prototypes
#define SERV_2_HEADER "Flame.h"
// the name of the Init function
#define SERV_2_INIT InitFlame
// the name of the run function
#define SERV_2_RUN RunFlame
// How big should this services Queue be?
#define SERV_2_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 3
#if NUM_SERVICES > 3
// the header file with the public function prototypes
#define SERV_3_HEADER "Spigot.h"
// the name of the Init function
#define SERV_3_INIT InitSpigot
// the name of the run function
#define SERV_3_RUN RunSpigot
// How big should this services Queue be?
#define SERV_3_QUEUE_SIZE 5
#endif
/****************************************************************************/
// These are the definitions for Service 4
#if NUM_SERVICES > 4
// the header file with the public function prototypes
#define SERV_4_HEADER "WaterGun.h"
// the name of the Init function
#define SERV_4_INIT InitWaterGun
// the name of the run function
#define SERV_4_RUN RunWaterGun
// How big should this services Queue be?
#define SERV_4_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 5
#if NUM_SERVICES > 5
// the header file with the public function prototypes
#define SERV_5_HEADER "Trigger.h"
// the name of the Init function
#define SERV_5_INIT InitTrigger
// the name of the run function
#define SERV_5_RUN RunTrigger
// How big should this services Queue be?
#define SERV_5_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 6
#if NUM_SERVICES > 6
// the header file with the public function prototypes
#define SERV_6_HEADER "ResetButton.h"
// the name of the Init function
#define SERV_6_INIT InitResetButton
// the name of the run function
#define SERV_6_RUN RunResetButton
// How big should this services Queue be?
#define SERV_6_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 7
#if NUM_SERVICES > 7
// the header file with the public function prototypes
#define SERV_7_HEADER "TestHarnessService7.h"
// the name of the Init function
#define SERV_7_INIT InitTestHarnessService7
// the name of the run function
#define SERV_7_RUN RunTestHarnessService7
// How big should this services Queue be?
#define SERV_7_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 8
#if NUM_SERVICES > 8
// the header file with the public function prototypes
#define SERV_8_HEADER "TestHarnessService8.h"
// the name of the Init function
#define SERV_8_INIT InitTestHarnessService8
// the name of the run function
#define SERV_8_RUN RunTestHarnessService8
// How big should this services Queue be?
#define SERV_8_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 9
#if NUM_SERVICES > 9
// the header file with the public function prototypes
#define SERV_9_HEADER "TestHarnessService9.h"
// the name of the Init function
#define SERV_9_INIT InitTestHarnessService9
// the name of the run function
#define SERV_9_RUN RunTestHarnessService9
// How big should this services Queue be?
#define SERV_9_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 10
#if NUM_SERVICES > 10
// the header file with the public function prototypes
#define SERV_10_HEADER "TestHarnessService10.h"
// the name of the Init function
#define SERV_10_INIT InitTestHarnessService10
// the name of the run function
#define SERV_10_RUN RunTestHarnessService10
// How big should this services Queue be?
#define SERV_10_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 11
#if NUM_SERVICES > 11
// the header file with the public function prototypes
#define SERV_11_HEADER "TestHarnessService11.h"
// the name of the Init function
#define SERV_11_INIT InitTestHarnessService11
// the name of the run function
#define SERV_11_RUN RunTestHarnessService11
// How big should this services Queue be?
#define SERV_11_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 12
#if NUM_SERVICES > 12
// the header file with the public function prototypes
#define SERV_12_HEADER "TestHarnessService12.h"
// the name of the Init function
#define SERV_12_INIT InitTestHarnessService12
// the name of the run function
#define SERV_12_RUN RunTestHarnessService12
// How big should this services Queue be?
#define SERV_12_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 13
#if NUM_SERVICES > 13
// the header file with the public function prototypes
#define SERV_13_HEADER "TestHarnessService13.h"
// the name of the Init function
#define SERV_13_INIT InitTestHarnessService13
// the name of the run function
#define SERV_13_RUN RunTestHarnessService13
// How big should this services Queue be?
#define SERV_13_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 14
#if NUM_SERVICES > 14
// the header file with the public function prototypes
#define SERV_14_HEADER "TestHarnessService14.h"
// the name of the Init function
#define SERV_14_INIT InitTestHarnessService14
// the name of the run function
#define SERV_14_RUN RunTestHarnessService14
// How big should this services Queue be?
#define SERV_14_QUEUE_SIZE 3
#endif
/****************************************************************************/
// These are the definitions for Service 15
#if NUM_SERVICES > 15
// the header file with the public function prototypes
#define SERV_15_HEADER "TestHarnessService15.h"
// the name of the Init function
#define SERV_15_INIT InitTestHarnessService15
// the name of the run function
#define SERV_15_RUN RunTestHarnessService15
// How big should this services Queue be?
#define SERV_15_QUEUE_SIZE 3
#endif
/****************************************************************************/
// Name/define the events of interest
// Universal events occupy the lowest entries, followed by user-defined events
typedef enum { ES_NO_EVENT = 0,
ES_ERROR, /* used to indicate an error from the service */
ES_INIT, /* used to transition from initial pseudo-state */
ES_TIMEOUT, /* signals that the timer has expired */
ES_SHORT_TIMEOUT, /* signals that a short timer has expired */
/* User-defined events start here */
ES_NEW_KEY, /* signals a new key received from terminal */
ES_LOCK,
ES_UNLOCK,
ES_BUTTON_HI,
ES_SPIGOT1_ON,
ES_SPIGOT2_ON,
ES_BOTH_SPIGOTS_ON,
ES_SPIGOT_OFF,
ES_ALL_FLAME_OFF,
ES_FLAME_HIT,
ES_PUMP_PRESSED,
ES_PUMP_RECOVERY,
ES_TRIGGER_PRESSED,
ES_TRIGGER_RELEASED,
// ES_GAME_WIN, USE: ES_ALL_FLAME_OFF instead
ES_GAME_TIMER_OUT,
ES_GAME_RESET,
// ES_GAME_LOSE, USE: ES_GAME_TIMER_OUT instead
ES_GAME_START} ES_EventTyp_t ;
/****************************************************************************/
// These are the definitions for the Distribution lists. Each definition
// should be a comma separated list of post functions to indicate which
// services are on that distribution list.
#define NUM_DIST_LISTS 1
#if NUM_DIST_LISTS > 0
#define DIST_LIST0 PostWaterReservoir
#endif
#if NUM_DIST_LISTS > 1
#define DIST_LIST1 PostTemplateFSM
#endif
#if NUM_DIST_LISTS > 2
#define DIST_LIST2 PostTemplateFSM
#endif
#if NUM_DIST_LISTS > 3
#define DIST_LIST3 PostTemplateFSM
#endif
#if NUM_DIST_LISTS > 4
#define DIST_LIST4 PostTemplateFSM
#endif
#if NUM_DIST_LISTS > 5
#define DIST_LIST5 PostTemplateFSM
#endif
#if NUM_DIST_LISTS > 6
#define DIST_LIST6 PostTemplateFSM
#endif
#if NUM_DIST_LISTS > 7
#define DIST_LIST7 PostTemplateFSM
#endif
/****************************************************************************/
// This are the name of the Event checking funcion header file.
#define EVENT_CHECK_HEADER "EventCheckers.h"
/****************************************************************************/
// This is the list of event checking functions
#define EVENT_CHECK_LIST Check4Keystroke, CheckSpigotEvents, CheckFlameEvents, CheckPulse, CheckTrigPull, CheckTrigRelease, CheckResetButton
/****************************************************************************/
// These are the definitions for the post functions to be executed when the
// corresponding timer expires. All 16 must be defined. If you are not using
// a timer, then you should use TIMER_UNUSED
// Unlike services, any combination of timers may be used and there is no
// priority in servicing them
#define TIMER_UNUSED ((pPostFunc)0)
#define TIMER0_RESP_FUNC PostServo
#define TIMER1_RESP_FUNC PostWaterReservoir
#define TIMER2_RESP_FUNC PostWaterGun
#define TIMER3_RESP_FUNC PostTrigger
#define TIMER4_RESP_FUNC PostResetButton
#define TIMER5_RESP_FUNC PostResetButton
#define TIMER6_RESP_FUNC PostResetButton
#define TIMER7_RESP_FUNC TIMER_UNUSED
#define TIMER8_RESP_FUNC TIMER_UNUSED
#define TIMER9_RESP_FUNC TIMER_UNUSED
#define TIMER10_RESP_FUNC TIMER_UNUSED
#define TIMER11_RESP_FUNC TIMER_UNUSED
#define TIMER12_RESP_FUNC TIMER_UNUSED
#define TIMER13_RESP_FUNC TIMER_UNUSED
#define TIMER14_RESP_FUNC TIMER_UNUSED
#define TIMER15_RESP_FUNC TIMER_UNUSED
/****************************************************************************/
// Give the timer numbers symbolc names to make it easier to move them
// to different timers if the need arises. Keep these definitions close to the
// definitions for the response functions to make it easier to check that
// the timer number matches where the timer event will be routed
// These symbolic names should be changed to be relevant to your application
#define SERVO_TIMER 0
#define PUMP_TIMER 1
#define PULSE_TIMER 2
#define TRIG_DB_TIMER 3
#define DEBOUNCE_TIMER 4
#define GAME_TIMER 5
#define RESET_TIMER 6
#define SERVICE0_TIMER 15
#endif /* CONFIGURE_H */