Code for C32 Microprocessor
Game Module - Checks Events and Handles Services
#include "stdio.h"
#include "ME218_C32.h"
#include "timers12.h"
#include "PWMS12.H"
#include "ADS12.H"
#include "GameControl.h"
#define GAME_OVER 0
#define GAME_ON 1
static char GameState = GAME_OVER;#define SERVO_GND_TIMER_NUMBER 0 // how long until servo GND
#define SERVO_GND_TIMER_DURATION 2000 // 2 sec
#define LASER_TIMER_NUMBER 1 // how long to fire the laser
#define LASER_TIMER_DURATION_EASY 5000 // 5 seconds
#define LASER_TIMER_DURATION_HARD 2500 // 5 seconds
#define LASER_TIMER_GAME_END 1000 // 1 second
#define SOLENOID_1_TIMER_NUMBER 2 // how long to release solenoid 1
#define SOLENOID_1_TIMER_DURATION 1000 // 1 sec
#define SOLENOID_2_TIMER_NUMBER 3 // how long to release solenoid 2
#define SOLENOID_2_TIMER_DURATION 1000 // 1 sec
#define BETWEEN_SOLENOIDS_TIMER_NUMBER 4 // how long to wait between solenoids
#define BETWEEN_SOLENOIDS_TIMER_DURATION 3000 // 1 sec
#define COUNTDOWN_CLOCK_NUMBER 5 // how long to wait between clock counts
#define COUNTDOWN_CLOCK_DURATION_EASY 1000 // 1 sec
#define COUNTDOWN_CLOCK_DURATION_HARD 500 // 500 ms
#define COUNTDOWN_RESET_PULSE_NUMBER 6 // how long to wait for reset pulse
#define COUNTDOWN_RESET_PULSE_DURATION 10 // 10 ms
#define COUNTDOWN_CLOCK_PULSE_NUMBER 7 // how long to pulse countdown clock
#define COUNTDOWN_CLOCK_PULSE_DURATION 100 // 100 ms
#define POT_CHANGE_THRESHOLD 2 // Required delta in Pot value to register event
#define POT_UNCHANGED 0 // State of Potentiometer
#define POT_CHANGED 1
#define POT1_PORT 0x0
#define POT2_PORT 0x1
#define POT3_PORT 0x2
#define COIN_INSERTED 1 // State of Coin Sensor
#define COIN_NOT_INSERTED 0
#define LASER_BROKEN 1 // State of Laser Break Phototransistor
#define LASER_NOT_BROKEN 0
#define EASY 0 // State definition
#define HARD 1
#define DIFFICULTY_CHANGE 1 // Relative state of Difficulty Switch
#define DIFFICULTY_NO_CHANGE 0
#define DIFFICULTY_SWITCH_BITMASK BIT3HI // Switch is input to port M, bit 3
static char DifficultyLevel = EASY;#define TARGET_HIT 1 // State of Target Phototransistor
#define TARGET_NOT_HIT 0
#define TARGET_1_BITMASK BIT2HI
static char LaserState = LASER_NOT_FIRING;#define LASER_FIRING 1
#define LASER_NOT_FIRING 0
static unsigned int LaserTime = LASER_TIMER_DURATION_EASY;#define DUTY_CYCLE_RATIO 50 // Relates potentiometer values to PWM duty cycle
#define MAX_DUTY_CYCLE 90 // Limits to prevent Servo lockup
#define MIN_DUTY_CYCLE 10
#define SOLENOID_1 BIT3HI // bit T3 controls lower solenoid
#define SOLENOID_2 BIT4HI // bit T4 controls upper solenoid
#define BETWEEN_SOLENOIDS 0 // State of solenoid action while waiting to load airlock
#define SOLENOID_HOLD 0 // controls for Solenoid set function
#define SOLENOID_RELEASE 1
#define RESET_LINE_LO 0 // State of Reset Line
#define RESET_LINE_HI 1
#define CLOCK_LINE_LO 0 // State of Clock Line
#define CLOCK_LINE_HI 1
#define COUNTS_PER_FIRE 5 // Number of clock expirations per fire
static unsigned int ClockSpeed = COUNTDOWN_CLOCK_DURATION_EASY;static char CountdownValue = 0;static unsigned int ClockValue = 0;
static char CheckPots(void);
static char CheckCoin(void);
static char CheckLaserBreak(void);
static char CheckDifficultySwitch(void);
static char CheckTarget1(void);
static char CheckTarget2(void);
static void SwitchDifficulty(void);
static void StartLaserTimer(void);
static void UpdateServos(void);
static void StartGame(void);
static void FireLaser(void);
static void StopFiringLaser(void);
static void SetSolenoid(char, char);
static void StartSolenoidTimer(char);
static void SetCountdownReset(char);
static void StartCountdownResetTimer(void);
static void StartCountdownTimer(void);
static void DecrementCountdownDisplay(void);
static void SetCountdownClock(char);
static void StartCountdownClockPulseTimer(void);
static void GroundServos(void);
static void StartServoTimer(void);
static void StopTimers(void);char CheckGameEvents()
{ if (TMRS12_IsTimerExpired(SOLENOID_1_TIMER_NUMBER) == TMRS12_EXPIRED) return SOLENOID_1_CLOCK_EXPIRE_EVENT; if (TMRS12_IsTimerExpired(SOLENOID_2_TIMER_NUMBER) == TMRS12_EXPIRED) return SOLENOID_2_CLOCK_EXPIRE_EVENT; if (TMRS12_IsTimerExpired(BETWEEN_SOLENOIDS_TIMER_NUMBER) == TMRS12_EXPIRED) return BETWEEN_SOLENOIDS_CLOCK_EXPIRE_EVENT; if (TMRS12_IsTimerExpired(COUNTDOWN_CLOCK_PULSE_NUMBER) == TMRS12_EXPIRED) return COUNTDOWN_CLOCK_PULSE_EXPIRE_EVENT; if (TMRS12_IsTimerExpired(COUNTDOWN_RESET_PULSE_NUMBER) == TMRS12_EXPIRED) return COUNTDOWN_RESET_PULSE_EXPIRE_EVENT; if (GameState == GAME_OVER)
{ if (CheckCoin() == COIN_INSERTED) return COIN_INSERT_EVENT; if (TMRS12_IsTimerExpired(SERVO_GND_TIMER_NUMBER) == TMRS12_EXPIRED) return SERVO_GND_TIMER_EXPIRE_EVENT;
} if (GameState == GAME_ON){ if (TMRS12_IsTimerExpired(LASER_TIMER_NUMBER) == TMRS12_EXPIRED) return LASER_CLOCK_EXPIRE_EVENT; if ((CountdownValue > 0) && (TMRS12_IsTimerExpired(COUNTDOWN_CLOCK_NUMBER) == TMRS12_EXPIRED)) return COUNTDOWN_CLOCK_EXPIRE_EVENT; if (CheckDifficultySwitch() == DIFFICULTY_CHANGE) return DIFFICULTY_CHANGE_EVENT; if (CheckTarget1() == TARGET_HIT) return TARGET1_HIT_EVENT; if (CheckLaserBreak() == LASER_BROKEN) return LASER_BREAK_EVENT; if (ClockValue == 0) return CLOCK_VALUE_TO_ZERO_EVENT; if (CheckPots() == POT_CHANGED) return POT_CHANGE_EVENT;
}
return NO_EVENT;
}void HandleGameEvents(char eventCode)
{
switch (eventCode)
{
case NO_EVENT:
break;
case LASER_BREAK_EVENT: if (LaserState == LASER_NOT_FIRING){
FireLaser();
}
printf("\n\rLASER broken");
break;
case DIFFICULTY_CHANGE_EVENT:
SwitchDifficulty();
break;
case TARGET1_HIT_EVENT:
StopTimers(); SetSolenoid(SOLENOID_1,SOLENOID_RELEASE); StartSolenoidTimer(SOLENOID_1); PTM |= BIT5HI; GameState = GAME_OVER; StartServoTimer(); printf("\n\rTarget 1 HIT");
printf("\r\nGAME OVER -- WAITING FOR COIN");
break;
case TARGET2_HIT_EVENT: break;
case LASER_CLOCK_EXPIRE_EVENT:
TMRS12_ClearTimerExpired(LASER_TIMER_NUMBER); StopFiringLaser(); printf("\n\rLaser Clock Expired");
break;
case POT_CHANGE_EVENT: UpdateServos(); break;
case SERVO_GND_TIMER_EXPIRE_EVENT:
TMRS12_ClearTimerExpired(SERVO_GND_TIMER_NUMBER); GroundServos(); PTM &= BIT5LO; printf("\n\rServo GND Timer Expired");
break;
case COIN_INSERT_EVENT:
StartGame(); printf("\n\rCoin Inserted");
break;
case SOLENOID_1_CLOCK_EXPIRE_EVENT:
TMRS12_ClearTimerExpired(SOLENOID_1_TIMER_NUMBER); SetSolenoid(SOLENOID_1,SOLENOID_HOLD); StartSolenoidTimer(BETWEEN_SOLENOIDS); printf("\n\rSolenoid 1 Held");
break;
case BETWEEN_SOLENOIDS_CLOCK_EXPIRE_EVENT:
TMRS12_ClearTimerExpired(BETWEEN_SOLENOIDS_TIMER_NUMBER); SetSolenoid(SOLENOID_2,SOLENOID_RELEASE); StartSolenoidTimer(SOLENOID_2); printf("\n\rSolenoid 2 Released");
break;
case SOLENOID_2_CLOCK_EXPIRE_EVENT:
TMRS12_ClearTimerExpired(SOLENOID_2_TIMER_NUMBER); SetSolenoid(SOLENOID_2,SOLENOID_HOLD); StopFiringLaser(); printf("\n\rSolenoid 2 Held\r\n\r\n\r\n\r\n");
break;
case COUNTDOWN_RESET_PULSE_EXPIRE_EVENT:
TMRS12_ClearTimerExpired(COUNTDOWN_RESET_PULSE_NUMBER); SetCountdownReset(RESET_LINE_LO); printf("\n\rReset Line set LO");
break;
case COUNTDOWN_CLOCK_PULSE_EXPIRE_EVENT:
TMRS12_ClearTimerExpired(COUNTDOWN_CLOCK_PULSE_NUMBER); SetCountdownClock(CLOCK_LINE_LO); printf("\n\rClock Line set LO");
break;
case COUNTDOWN_CLOCK_EXPIRE_EVENT:
TMRS12_ClearTimerExpired(COUNTDOWN_CLOCK_NUMBER); DecrementCountdownDisplay(); if (CountdownValue > 0)
{
StartCountdownTimer(); }
printf("\n\rCountdown Clock Expired");
break;
case CLOCK_VALUE_TO_ZERO_EVENT:
StopTimers(); StopFiringLaser(); StartServoTimer(); GameState = GAME_OVER; printf("\n\r Game Clock to Zero --> YOU LOSE!");
break;
}
}
static char CheckPots()
{
static short lastPot1State = -1;
static short lastPot2State = -1;
static short lastPot3State = -1;
static short currentPot1State;
static short currentPot2State;
static short currentPot3State;
currentPot1State = ADS12_ReadADPin(POT1_PORT);
currentPot2State = ADS12_ReadADPin(POT2_PORT);
currentPot3State = ADS12_ReadADPin(POT3_PORT); if ((currentPot1State - lastPot1State > POT_CHANGE_THRESHOLD)
|| (lastPot1State - currentPot1State > POT_CHANGE_THRESHOLD))
{
lastPot1State = currentPot1State;
return POT_CHANGED;
}
if ((currentPot2State - lastPot2State > POT_CHANGE_THRESHOLD)
|| (lastPot2State - currentPot2State > POT_CHANGE_THRESHOLD))
{
lastPot2State = currentPot2State;
return POT_CHANGED;
}
if ((currentPot3State - lastPot3State > POT_CHANGE_THRESHOLD)
|| (lastPot3State - currentPot3State > POT_CHANGE_THRESHOLD))
{
lastPot3State = currentPot3State;
return POT_CHANGED;
}
return POT_UNCHANGED;
}
static void UpdateServos()
{
static short currentPot1State;
static short currentPot2State;
static short currentPot3State;
unsigned char Servo1DutyCycle;
unsigned char Servo2DutyCycle;
unsigned char Servo3DutyCycle;
currentPot1State = ADS12_ReadADPin(POT1_PORT);
currentPot2State = ADS12_ReadADPin(POT2_PORT);
currentPot3State = ADS12_ReadADPin(POT3_PORT);
if(currentPot1State >= 0)
{
Servo1DutyCycle = (unsigned char)((unsigned int)DUTY_CYCLE_RATIO*currentPot1State/512);
if (Servo1DutyCycle > MAX_DUTY_CYCLE) Servo1DutyCycle = MAX_DUTY_CYCLE;
if (Servo1DutyCycle < MIN_DUTY_CYCLE) Servo1DutyCycle = MIN_DUTY_CYCLE;
if (PWMS12_SetDuty(Servo1DutyCycle,PWMS12_CHAN0) != PWMS12_OK)
{
printf("\n\rERROR setting duty for PWM chan 0");
}
}
if(currentPot2State >= 0)
{
Servo2DutyCycle = (unsigned char)((unsigned int)DUTY_CYCLE_RATIO*currentPot2State/512);
if (Servo2DutyCycle > MAX_DUTY_CYCLE) Servo2DutyCycle = MAX_DUTY_CYCLE;
if (Servo2DutyCycle < MIN_DUTY_CYCLE) Servo2DutyCycle = MIN_DUTY_CYCLE;
if (PWMS12_SetDuty(Servo2DutyCycle,PWMS12_CHAN1) != PWMS12_OK)
{
printf("\n\rERROR setting duty for PWM chan 1");
}
}
if(currentPot3State >= 0)
{
Servo3DutyCycle = (unsigned char)((unsigned int)DUTY_CYCLE_RATIO*currentPot3State/512);
if (Servo3DutyCycle > MAX_DUTY_CYCLE) Servo3DutyCycle = MAX_DUTY_CYCLE;
if (Servo3DutyCycle < MIN_DUTY_CYCLE) Servo3DutyCycle = MIN_DUTY_CYCLE;
if (PWMS12_SetDuty(Servo3DutyCycle,PWMS12_CHAN2) != PWMS12_OK)
{
printf("\n\rERROR setting duty for PWM chan 2");
}
}
}
static void StartLaserTimer()
{
if ((TMRS12_InitTimer(LASER_TIMER_NUMBER, LaserTime)) != TMRS12_OK)
{
printf("\n\rERROR starting laser timer");
}
}
static char CheckCoin()
{ static char coin_status = COIN_NOT_INSERTED;
if ((PTM & BIT0HI) && (coin_status == COIN_INSERTED))
{
coin_status = COIN_NOT_INSERTED;
return COIN_NOT_INSERTED;
} else if (((PTM & BIT0HI) == 0) && (coin_status == COIN_NOT_INSERTED))
{
coin_status = COIN_INSERTED;
return COIN_INSERTED;
}
return NO_EVENT;
}
static char CheckLaserBreak()
{ static char laserBreak = LASER_NOT_BROKEN;
if ((PTM & BIT1HI) && (laserBreak == LASER_BROKEN))
{
laserBreak = LASER_NOT_BROKEN;
return LASER_NOT_BROKEN;
} else if (((PTM & BIT1HI) == 0) && (laserBreak == LASER_NOT_BROKEN))
{
laserBreak = LASER_BROKEN;
return LASER_BROKEN;
}
return NO_EVENT;
}
static char CheckDifficultySwitch()
{
if ( (PTM & DIFFICULTY_SWITCH_BITMASK) && (DifficultyLevel == EASY) )
{
return DIFFICULTY_CHANGE;
}
else if (((PTM & DIFFICULTY_SWITCH_BITMASK) == 0) && (DifficultyLevel == HARD))
{
return DIFFICULTY_CHANGE;
}
return DIFFICULTY_NO_CHANGE;
}
static char CheckTarget1()
{
static char lastTarget1 = TARGET_NOT_HIT; if (( PTM & TARGET_1_BITMASK ) && (lastTarget1 == TARGET_NOT_HIT))
{
lastTarget1 = TARGET_HIT;
return TARGET_HIT;
} else if (((PTM & TARGET_1_BITMASK) == 0) && (lastTarget1 == TARGET_HIT))
{
lastTarget1 = TARGET_NOT_HIT;
return TARGET_NOT_HIT;
}
return NO_EVENT;
}
static char CheckTarget2()
{ if ( PTM & TARGET_2_BITMASK ) return TARGET_HIT;
return TARGET_NOT_HIT;
}
static void StartGame()
{
GameState = GAME_ON;
PTM &= BIT5LO; SetCountdownReset(RESET_LINE_HI);
printf("\n\rReset Line Set HI");
StartCountdownResetTimer();
ClockValue = 25;
}
static void FireLaser()
{ PTM |= BIT4HI;
LaserState = LASER_FIRING;
CountdownValue = 5;
printf("\n\rLaser Firing...");
if (DifficultyLevel == HARD){
ClockSpeed = COUNTDOWN_CLOCK_DURATION_HARD;
LaserTime = LASER_TIMER_DURATION_HARD;
}
else if (DifficultyLevel == EASY){
ClockSpeed = COUNTDOWN_CLOCK_DURATION_EASY;
LaserTime = LASER_TIMER_DURATION_EASY;
}
StartLaserTimer();
StartCountdownTimer();
}
static void StopFiringLaser()
{ printf("\n\rLaser DONE Firing...");
PTM &= BIT4LO;
LaserState = LASER_NOT_FIRING;
}
static void SetSolenoid(char solenoid_number, char solenoid_state)
{
if (solenoid_state == SOLENOID_RELEASE)
{
PTT |= solenoid_number;
}
if (solenoid_state == SOLENOID_HOLD)
{
PTT &= ~solenoid_number;
}
}
static void StartSolenoidTimer(char solenoid_number)
{
if (solenoid_number == SOLENOID_1)
{
if ((TMRS12_InitTimer(SOLENOID_1_TIMER_NUMBER, SOLENOID_1_TIMER_DURATION)) != TMRS12_OK)
{
printf("\n\rERROR starting solenoid 1 timer");
}
}
if (solenoid_number == SOLENOID_2)
{
if ((TMRS12_InitTimer(SOLENOID_2_TIMER_NUMBER, SOLENOID_2_TIMER_DURATION)) != TMRS12_OK)
{
printf("\n\rERROR starting solenoid 2 timer");
}
}
if (solenoid_number == BETWEEN_SOLENOIDS)
{
if ((TMRS12_InitTimer(BETWEEN_SOLENOIDS_TIMER_NUMBER, BETWEEN_SOLENOIDS_TIMER_DURATION)) != TMRS12_OK)
{
printf("\n\rERROR starting between solenoids timer");
}
}
}
static void SwitchDifficulty()
{
if (DifficultyLevel == EASY)
{
DifficultyLevel = HARD;
printf("\n\rDifficulty Changed to HARD");
}
else
{
DifficultyLevel = EASY;
ClockSpeed = COUNTDOWN_CLOCK_DURATION_EASY;
LaserTime = LASER_TIMER_DURATION_EASY;
printf("\n\rDifficulty Changed to EASY");
}
}
static void SetCountdownReset(char reset_value)
{
if (reset_value == RESET_LINE_HI)
{
PTT |= BIT6HI;
}
if (reset_value == RESET_LINE_LO)
{
PTT &= BIT6LO;
}
}
static void StartCountdownResetTimer()
{
if ((TMRS12_InitTimer(COUNTDOWN_RESET_PULSE_NUMBER, COUNTDOWN_RESET_PULSE_DURATION)) != TMRS12_OK)
{
printf("\n\rERROR starting reset pulse timer");
}
}
static void StartCountdownTimer()
{
if ((TMRS12_InitTimer(COUNTDOWN_CLOCK_NUMBER, ClockSpeed)) != TMRS12_OK)
{
printf("\n\rERROR starting countdown clock");
}
}
static void DecrementCountdownDisplay()
{
CountdownValue = CountdownValue - 1;
ClockValue = ClockValue - 1;
SetCountdownClock(CLOCK_LINE_HI);
printf("\n\rClock Line set HI");
StartCountdownClockPulseTimer();
printf("\n\rClock to value %i",ClockValue);
}
static void SetCountdownClock(char clock_value)
{
if (clock_value == CLOCK_LINE_HI)
{
PTT |= BIT5HI;
}
if (clock_value == CLOCK_LINE_LO)
{
PTT &= BIT5LO;
}
}
static void StartCountdownClockPulseTimer()
{
if ((TMRS12_InitTimer(COUNTDOWN_CLOCK_PULSE_NUMBER, COUNTDOWN_CLOCK_PULSE_DURATION)) != TMRS12_OK)
{
printf("\n\rERROR starting countdown clock pulse timer");
}
}
static void GroundServos()
{
PWMS12_SetDuty(0,PWMS12_CHAN0);
PWMS12_SetDuty(0,PWMS12_CHAN1);
PWMS12_SetDuty(0,PWMS12_CHAN2);
printf("\n\rServos Grounded");
}
static void StartServoTimer()
{
if ((TMRS12_InitTimer(SERVO_GND_TIMER_NUMBER, SERVO_GND_TIMER_DURATION)) != TMRS12_OK)
{
printf("\n\rERROR starting servo timer");
}
}
static void StopTimers()
{
TMRS12_StopTimer(LASER_TIMER_NUMBER); TMRS12_StopTimer(COUNTDOWN_CLOCK_NUMBER);
}