Skip to content

Instantly share code, notes, and snippets.

@michaellin
Created December 1, 2015 04:06
Show Gist options
  • Save michaellin/1774a7e63313cc6346ce to your computer and use it in GitHub Desktop.
Save michaellin/1774a7e63313cc6346ce to your computer and use it in GitHub Desktop.
/*********************************************************
Wrench Service Module
(a service that implements a state machine)
Aaron Manheim 11/07/15
**********************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "utils/uartstdio.h"
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "ES_Port.h"
#include "termio.h"
#include "WrenchService.h"
#include "WrenchHelpers.h"
#include "BucketService.h"
#include "Audio2.h"
#define ClearBits 0x00
#define WrenchOnLED_time 500
/*---------------------------- Module Variables ---------------------------*/
// with the introduction of Gen2, we need a module level Priority variable
static uint8_t MyPriority;
static uint16_t WrenchStartTime = 0;
static uint16_t TimeDelta = 0;
static WrenchServiceState_t CurrentState;
static int CurrentInputState;
static int LastInputState = 0;
static int LED_Bin =0;
static int Last_LED_Bin = -1;
/*********************************************************
InitaializeWrenchService
Takes a priority number, returns True.
**********************************************************/
bool InitializeWrenchService( uint8_t Priority )
{
ES_Event ThisEvent;
//Initialize the MyPriority variable with the passed in parameter
MyPriority = Priority;
//Initialize the port line to read analog input for Pot
Wrench_Pot_Init();
//Initialize the port lines to light wrench LEDs and SR_Init_LED()
Wrench_SR_Init();
//Turn off all LEDs
Wrench_SR_Write(ClearBits);
//Sample pot port line and use it to initialize LastWrenchState variable (probably as bins of values)
LastInputState = Wrench_Pot_Bin(); //Int between 1 and 15
//Set CurrentState to be InitWrenchService
CurrentState = InitWrenchService;
//Set a random LED Bin
//SetLED_Bin();
//Post event ES_Init to InitialzeWrench queue (this service)
ThisEvent.EventType = ES_INIT;
PostWrenchService( ThisEvent);
//End of InitializeWrenchService
return true;
}
/*********************************************************
Post WrenchSerivce
Takes an ES_Event, returns bool
**********************************************************/
bool PostWrenchService( ES_Event ThisEvent )
{
return ES_PostToService( MyPriority, ThisEvent);
}
/*********************************************************
CheckWrenchEvents
Takes no parameters, returns True if an event was posted
**********************************************************/
bool CheckWrenchEvents ( void)
{
//Set local variables
ES_Event ThisEvent;
bool ReturnVal = false;
//Get the current wrench input state from the anolog input line
TimeDelta = ES_Timer_GetTime()-WrenchStartTime;
if (TimeDelta>3000){
ThisEvent.EventType = ES_WRENCH2GOAL;
ThisEvent.EventParam = TimeDelta;
PostBucketService(ThisEvent);
WrenchStartTime = ES_Timer_GetTime();
}
CurrentInputState = Wrench_Pot_Bin();
static uint16_t PotValue; //test
PotValue = Wrench_Pot_Read(); //test
//printf("\n\rPotBin: %d ",CurrentInputState);
//If Current input state of pot is different from LastInputState or Current input State is in LED bin
if ((CurrentInputState != LastInputState)||(CurrentInputState == LED_Bin)){
// if (CurrentInputState != LastInputState){ //for loop just for printf
// printf("\n\rWrench in Bin: %d ",CurrentInputState);
// printf (" Move to Bin: %d", LED_Bin);
// printf("PotValue: %d",PotValue);
// }
//If current LED on is in Wrench_Bin
if (CurrentInputState == LED_Bin){
// PostEvent ES_ReachedLED with the parameter of the Current Time
ThisEvent.EventType = ES_ReachedLED;
ThisEvent.EventParam = ES_Timer_GetTime();
PostWrenchService(ThisEvent);
// Endif
}
// Else
else {
// PostEvent ES_NotReachedLED
ThisEvent.EventType = ES_NotReachedLED;
PostWrenchService(ThisEvent);
// endElse
}
// Set ReturnVal True
ReturnVal = true;
//Endif
}
//Set LastInputState to CurrentInputState
LastInputState = CurrentInputState;
//Return ReturnVal
return ReturnVal;
//End of CheckWrenchEvents
}
/*********************************************************
RunWrenchService
Takes an ES_Event, Returs an ES_Event.
The EventType field will be one of: ES_Init, ES_ReachedLED,
ES_NotReachedLED, ES_TimeOut, START_BUTTON_DBDOWN, ES_WRENCH2GOAL
**********************************************************/
ES_Event RunWrenchService(ES_Event ThisEvent)
{
//Set NextState to CurrentState
WrenchServiceState_t NextState = CurrentState;
//Setup ReturnEvent
ES_Event ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors
//Switch CurrentState :
switch (CurrentState){
// CurrentState is InitWrenchService
case InitWrenchService :
// If ThisEvent is ES_Init
if (ThisEvent.EventType == ES_INIT){
// Set NextState to WaitingForStart
NextState = WaitingForStart;
// Endif
}
// End InitWrenchServiceBlock
break;
// CurrentState is WaitingForStart
case WaitingForStart :
// If ThisEvent is START_BUTTON_DBDOWN
if (ThisEvent.EventType == ES_START_BUTTON_DBDOWN){
// Set NextState to Wrench2Position
NextState = Wrench2Position;
// Set WrenchStartTime = Get Current Time
WrenchStartTime = ES_Timer_GetTime();
// Turn on a random LED and save its position (LED_Position)
SetLED_Bin();
//printf("\n\rMove to this bin: %d", LED_Bin);
// Endif
}
// End WaitingForStart block
break;
// CurrentState is Wrench2Position
case Wrench2Position:
// TimeDelta = ES_Timer_GetTime()-WrenchStartTime;
// if (TimeDelta>2000){
// ThisEvent.EventType = ES_WRENCH2GOAL;
// ThisEvent.EventParam = TimeDelta;
// PostBucketService(ThisEvent);
// WrenchStartTime = ES_Timer_GetTime();
// }
//printf("Move Wrench: %d", LED_Bin);
// If ThisEvent is ES_ReachedLED
if (ThisEvent.EventType == ES_ReachedLED){
// Start WrenchTimer for 1 second
ES_Timer_InitTimer(WrenchOnLED, WrenchOnLED_time); //WrenchOnLED = 4;
// Set NextState to WrenchInPosition
NextState = WrenchInPosition;
// Endif
}
// If ThisEvent is PipeDown (or PipeTimerTimeout)
if ((ThisEvent.EventType == ES_TIMEOUT)&&(ThisEvent.EventParam == PIPE_TIMER)){
// Set NextState to PipeBurst
NextState = PipeBurst;
// Turn on LEDs
Wrench_SR_Write(0xff);
// Endif
}
if (ThisEvent.EventType == ES_GAMEOVER){
//Set NextState to WaitForStart
NextState = WaitingForStart;
//Turn off all LEDs
Wrench_SR_Write(ClearBits);
}
// End Wrench2Position block
break;
//
// CurrentState is PipeBurst
case PipeBurst :
// If ThisEvent is (ES_PIPE_BUTTON1_DBDOWN) or (ES_PIPE_BUTTON2_DBDOWN) or (ES_FAIL_DRIP_CATCH)
if (ThisEvent.EventType == ES_PIPE_RECOVERED){
Wrench_SR_Write(0x00);
// Turn on a random LED and save its position (LED_Bin)
SetLED_Bin();
// Set NextState to Wrench2Position
NextState = Wrench2Position;
// Set WrenchStartTime = Get Current Time
WrenchStartTime = ES_Timer_GetTime();
// Endif
}
// End PipeBurst block
break;
// CurrentState is WrenchInPosition
case WrenchInPosition :
// If ThisEvent is ES_NotReachedLED
if (ThisEvent.EventType == ES_NotReachedLED){
// Set NextState to Wrench2Position
NextState = Wrench2Position;
// Endif
}
// If ThisEvent is ES_TimeOut (for WrenchOnLED timer - timer 4)
if ((ThisEvent.EventType == ES_TIMEOUT)&&(ThisEvent.EventParam == WrenchOnLED)){
//printf("\r\n Correct Position!");
// TimeDelta = GetCurrentTime - WrenchStartTime
TimeDelta = ES_Timer_GetTime() - WrenchStartTime;
// Post to bucket service ES_WRENCH2GOAL with parameter of TimeDelta (uint16)
ThisEvent.EventType = ES_WRENCH2GOAL;
ThisEvent.EventParam = TimeDelta;
PostBucketService(ThisEvent);
//Post Success sound to sound service
ThisEvent.EventType = ES_PLAY_TUNE;
ThisEvent.EventParam = SuccessWrench;
PostAudio2(ThisEvent);
// Set WrenchStartTime = Get Current Time
WrenchStartTime = ES_Timer_GetTime();
//Turn on a random LED and save its position
SetLED_Bin();
// Set NextState to Wrench2Position
NextState = Wrench2Position;
// EndIf
}
// If ThisEvent is PipeDown (or PipeTimerTimeout)
if ((ThisEvent.EventType == ES_TIMEOUT)&&(ThisEvent.EventParam == PIPE_TIMER)){
// Set NextState to PipeBurst
NextState = PipeBurst;
// Turn on LEDs
Wrench_SR_Write(0xff);
// Endif
}
//if ((ThisEvent.EventType == ES_TIMEOUT)&&(ThisEvent.EventParam == ED_TIMER)){
if (ThisEvent.EventType == ES_GAMEOVER){
//Set NextState to WaitForStart
NextState = WaitingForStart;
//Turn off all LEDs
Wrench_SR_Write(ClearBits);
LED_Bin=0;
}
//End WrenchInPosition block
break;
//End of Switch
}
//Set CurrentState to Next State
CurrentState = NextState;
//Return ES_NO_EVENT
ReturnEvent.EventType = ES_NO_EVENT;
return ReturnEvent;
//End Of RunWrench Service
}
/*********************************************************
SetLED_Bin
Takes no parameters, returns nothing
Changes the module level variable LED_Bin to represent the new lit LED
**********************************************************/
void SetLED_Bin( void){
/* random int between 0 and 7 */
//printf("SetNewLED");
int r = rand() % 8;
//LED_Bin = 2*r+1; //For 15 bins
LED_Bin = r+1; //For 8 bins
while (Last_LED_Bin != LED_Bin){
//Turn on the right LED
if (r==0){
Wrench_SR_Write(BIT0HI);}
if (r==1){
Wrench_SR_Write(BIT1HI);}
if (r==2){
Wrench_SR_Write(BIT2HI);}
if (r==3){
Wrench_SR_Write(BIT3HI);}
if (r==4){
Wrench_SR_Write(BIT4HI);}
if (r==5){
Wrench_SR_Write(BIT5HI);}
if (r==6){
Wrench_SR_Write(BIT6HI);}
if (r==7){
Wrench_SR_Write(BIT7HI);}
Last_LED_Bin=LED_Bin;
}
//printf("LED_Bin: %d", LED_Bin);
}
/************************************************************************
Main Funciton for Testing
#define clrScrn() printf("\x1b[2J")
int main(void){
// initialize the timer sub-system and console I/O
_HW_Timer_Init(ES_Timer_RATE_1mS);
TERMIO_Init();
clrScrn();
// When doing testing, it is useful to announce just which program
// is running.
puts("\r Toggle Problem 2.2 \r");
printf("%s %s\n",__TIME__, __DATE__);
printf("\n\r\n");
//Hardware initializations
InitializeWrenchService( 1);
//Test analog input:
uint16_t ThePotValue;
while(1){
ThePotValue = Wrench_Pot_Read();
printf("\n\rPot: %d",ThePotValue); //Pin E0
}
// if you fall off the end of your code, then hang around here
for(;;)
;
}
************************************************************************/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment