Created
December 1, 2015 03:57
-
-
Save michaellin/ac3b7f48c61901e6b205 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**************************************************************************** | |
Module | |
PipeSegment.c | |
Description | |
This service implements a state machine to control the movement of | |
the two pipe segments. | |
Author | |
Margaret Coad | |
Date | |
11/10/15 | |
****************************************************************************/ | |
/*----------------------------- 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 "PipeSegment.h" | |
#include "Audio1.h" | |
#include "Audio2.h" | |
#include "PWM12Tiva.h" | |
#include "BucketService.h" | |
#include "WrenchService.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" | |
/*----------------------------- Module Defines ----------------------------*/ | |
#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 | |
*/ | |
/*---------------------------- Module Variables ---------------------------*/ | |
// Data private to the module: MyPriority, CurrentState | |
static uint8_t MyPriority; | |
static PipeSegmentState_t CurrentState; | |
/*------------------------------ Module Code ------------------------------*/ | |
/**************************************************************************** | |
Function | |
InitPipeSegment | |
Parameters | |
uint8_t : the priority of this service | |
Returns | |
bool, false if error in initialization, true otherwise | |
Description | |
Saves away the priority, and does any | |
other required initialization for this service | |
Notes | |
Author | |
Margaret Coad, 11/10/15 | |
****************************************************************************/ | |
bool InitPipeSegment ( uint8_t Priority ) | |
{ | |
//Initialize the MyPriority variable with the passed in parameter | |
MyPriority = Priority; | |
//Initialize the port lines to write to PipeServo1 (PD0) and PipeServo2 //(PD1) | |
// Enable GPIO Port D | |
HWREG(SYSCTL_RCGCGPIO) |= BIT3HI; | |
// Wait until peripheral reports that clock is ready | |
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R3) !=SYSCTL_PRGPIO_R3); | |
// Set bits 0 and 1 on Port D to be digital I/O lines | |
HWREG(GPIO_PORTD_BASE+GPIO_O_DEN) |= (GPIO_PIN_0 | GPIO_PIN_1); | |
// Set bits 0 and 1 on Port D to be outputs | |
HWREG(GPIO_PORTD_BASE+GPIO_O_DIR) |= (GPIO_PIN_0 | GPIO_PIN_1); | |
//Initialize the port lines to write to PipeLED1 (PA4) and PipeLED2 //(PF3) | |
// Enable GPIO Port A | |
HWREG(SYSCTL_RCGCGPIO) |= BIT0HI; | |
// Enable GPIO Port F | |
HWREG(SYSCTL_RCGCGPIO) |= BIT5HI; | |
// Wait until peripheral reports that clock is ready | |
while ((HWREG(SYSCTL_PRGPIO) & SYSCTL_PRGPIO_R0) !=SYSCTL_PRGPIO_R0); | |
// Set bit 4 on Port A and bit 3 on Port F to be digital I/O lines | |
HWREG(GPIO_PORTA_BASE+GPIO_O_DEN) |= (GPIO_PIN_4); | |
HWREG(GPIO_PORTF_BASE+GPIO_O_DEN) |= GPIO_PIN_3; | |
// Set bits 4 on Port A and bit 3 on Port F to be outputs | |
HWREG(GPIO_PORTA_BASE+GPIO_O_DIR) |= (GPIO_PIN_4); // Pipe 1 LED | |
HWREG(GPIO_PORTF_BASE+GPIO_O_DIR) |= (GPIO_PIN_3); // Pipe 2 LED | |
//Start both pipes in the “pipes in” position | |
// Set frequency for the group for pins D0 and D1 to 50 Hz | |
PWM_TIVA_SetFreq(50, 4); | |
// Set pulse width on pin D0 for 0 degrees | |
PWM_TIVA_SetPulseWidth(700, 8); | |
// Set pulse width on pin D1 for 180 degrees | |
PWM_TIVA_SetPulseWidth(3000, 9); | |
//Set CurrentState to BothPipesIn | |
CurrentState = BothPipesIn; | |
//End of InitializePipeSegment (return True) | |
return true; | |
} | |
/**************************************************************************** | |
Function | |
PostPipeSegment | |
Parameters | |
EF_Event ThisEvent, the event to post to the queue | |
Returns | |
bool false if the Enqueue operation failed, true otherwise | |
Description | |
Posts an event to this state machine's queue | |
Notes | |
Author | |
Margaret Coad, 11/10/15 | |
****************************************************************************/ | |
bool PostPipeSegment( ES_Event ThisEvent ) | |
{ | |
return ES_PostToService( MyPriority, ThisEvent); | |
} | |
/**************************************************************************** | |
Function | |
RunPipeSegment (implements 3-state state machine for pipe segments) | |
Parameters | |
ES_Event : the event to process | |
Returns | |
ES_Event, ES_NO_EVENT if no error, ES_ERROR otherwise | |
Description | |
The EventType field of ThisEvent will be one of: | |
ES_PIPE1_BUTTON_DBDOWN, ES_PIPE2_BUTTON_DBDOWN, ES_TIMEOUT, | |
ES_GAMEOVER, ES_PIPE_DOWN_LOST | |
Notes | |
Author | |
Margaret Coad, 11/10/15 | |
****************************************************************************/ | |
ES_Event RunPipeSegment( ES_Event ThisEvent ) | |
{ | |
ES_Event ReturnEvent; | |
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors | |
//Local Variables: NextState | |
PipeSegmentState_t NextState; | |
//Set NextState to CurrentState | |
NextState = CurrentState; | |
//Based on the state of the CurrentState variable choose one of | |
//the following blocks of code: | |
switch (CurrentState){ | |
case BothPipesIn: | |
// If the pipe timer goes off, we should move one of | |
// the pipes out | |
if ((ThisEvent.EventType == ES_TIMEOUT) && | |
(ThisEvent.EventParam == PIPE_TIMER)) { | |
// Play a bad sound to show that the pipe is | |
// out | |
ES_Event ThatEvent; | |
ThatEvent.EventType = ES_PLAY_TUNE; | |
ThatEvent.EventParam = PipeOut; | |
PostAudio1(ThatEvent); | |
PostAudio2(ThatEvent); | |
srand(ES_Timer_GetTime()); | |
uint8_t whichPipe = rand()%2; | |
// Calculate a random integer (either 0 or 1) | |
// to decide which pipe to move | |
if (whichPipe == 0){ | |
// Move pipe 1 to the out position | |
// Set pulse width on pin D0 for 90 | |
// degrees | |
PWM_TIVA_SetPulseWidth(2050, 8); | |
NextState = Pipe1Out; | |
// Turn on pipe 1 button LED | |
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA+ALL_BITS)) | |
|= (BIT4HI); | |
} | |
else { | |
// Move pipe 2 to the out position | |
// Set pulse width on pin D1 for 90 | |
// degrees | |
PWM_TIVA_SetPulseWidth(1850, 9); | |
NextState = Pipe2Out; | |
// Turn on pipe button LED | |
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA+ALL_BITS)) | |
|= (BIT3HI); | |
} | |
} | |
// If game is over | |
else if (ThisEvent.EventType == ES_GAMEOVER) { | |
// Move into state where pipe timer will be | |
// ignored | |
NextState = InCelebration; | |
} | |
break; | |
case Pipe1Out: | |
if ((ThisEvent.EventType == ES_PIPE_DOWN_LOST) || | |
(ThisEvent.EventType == ES_PIPE1_BUTTON_DBDOWN)) { | |
// Turn off Pipe button LEDs | |
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA+ALL_BITS)) | |
&= (BIT4LO); | |
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA+ALL_BITS)) | |
&= (BIT3LO); | |
// Play a good sound to show that the pipe is | |
back in | |
ES_Event ThatEvent; | |
ThatEvent.EventType = ES_PLAY_TUNE; | |
ThatEvent.EventParam = PipeIn; | |
PostAudio1(ThatEvent); | |
PostAudio2(ThatEvent); | |
// Post Event ES_PIPE_RECOVERED to Bucket Service, | |
// Wrench Service, Audio1, and Audio2 | |
ES_Event OtherEvent; | |
OtherEvent.EventType = ES_PIPE_RECOVERED; | |
OtherEvent.EventParam = ES_Timer_GetTime(); | |
PostBucketService(OtherEvent); | |
PostWrenchService(OtherEvent); | |
PostAudio1(OtherEvent); | |
PostAudio2(OtherEvent); | |
// Move Pipe1 to the in position | |
// Set pulse width on pin D0 for 0 | |
// degrees | |
PWM_TIVA_SetPulseWidth(700, 8); | |
NextState = BothPipesIn; | |
// Start pipe timer for 16 seconds | |
ES_Timer_InitTimer(PIPE_TIMER, 16000); | |
} | |
// If game is over | |
else if (ThisEvent.EventType == ES_GAMEOVER) { | |
// Turn off pipe lights | |
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA+ALL_BITS)) | |
&= (BIT4LO); | |
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA+ALL_BITS)) | |
&= (BIT3LO); | |
// Set pulse width on pin D0 for 0 | |
// degrees | |
PWM_TIVA_SetPulseWidth(700, 8); | |
NextState = InCelebration; | |
} | |
break; | |
case Pipe2Out: | |
if ((ThisEvent.EventType == ES_PIPE_DOWN_LOST) || | |
(ThisEvent.EventType == ES_PIPE2_BUTTON_DBDOWN)) { | |
// Turn off Pipe button LEDs | |
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA+ALL_BITS)) | |
&= (BIT4LO); | |
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA+ALL_BITS)) | |
&= (BIT3LO); | |
// Play a good sound to show that the pipe is | |
// back in | |
ES_Event ThatEvent; | |
ThatEvent.EventType = ES_PLAY_TUNE; | |
ThatEvent.EventParam = PipeIn; | |
PostAudio1(ThatEvent); | |
PostAudio2(ThatEvent); | |
// Post Event ES_PIPE_RECOVERED to Bucket Service | |
// and Wrench Service | |
ES_Event OtherEvent; | |
OtherEvent.EventType = ES_PIPE_RECOVERED; | |
OtherEvent.EventParam = ES_Timer_GetTime(); | |
PostBucketService(OtherEvent); | |
PostWrenchService(OtherEvent); | |
PostAudio1(OtherEvent); | |
PostAudio2(OtherEvent); | |
// Move Pipe2 to the in position | |
// Set pulse width on pin D1 for 180 | |
// degrees | |
PWM_TIVA_SetPulseWidth(3000, 9); | |
NextState = BothPipesIn; | |
// Start pipe timer for 16 seconds | |
ES_Timer_InitTimer(PIPE_TIMER, 16000); | |
} | |
// If the game is over | |
else if (ThisEvent.EventType == ES_GAMEOVER) { | |
// Turn off button lights | |
HWREG(GPIO_PORTA_BASE+(GPIO_O_DATA+ALL_BITS)) | |
&= (BIT4LO); | |
HWREG(GPIO_PORTF_BASE+(GPIO_O_DATA+ALL_BITS)) | |
&= (BIT3LO); | |
// Set pulse width on pin D1 for 180 | |
// degrees | |
PWM_TIVA_SetPulseWidth(3000, 9); | |
NextState = InCelebration; | |
} | |
break; | |
case InCelebration: | |
if (ThisEvent.EventType == ES_START_BUTTON_DBDOWN) | |
{ | |
NextState = BothPipesIn; | |
} | |
break; | |
} | |
//Set CurrentState to NextState | |
CurrentState = NextState; | |
//Return ES_NO_EVENT | |
return ReturnEvent; | |
} | |
/*************************************************************************** | |
private functions | |
***************************************************************************/ | |
/*------------------------------- Footnotes -------------------------------*/ | |
/*------------------------------ End of file ------------------------------*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment