/****************************************************************************
 Module
   TeamColorAndGameLEDs.c

 Revision
   1.0.1

 Description
   Checks the switch to see what color we are playing as
   Also has the code to turn on and off the Game LED & color LEDs

 Notes

 History
 When           Who     What/Why
 -------------- ---     --------
 02/26/18 17:34 edzc    first pass

****************************************************************************/
// the common headers for C99 types
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>

// 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_PWM.h"
#include "inc/hw_timer.h"
#include "inc/hw_nvic.h"
#include "inc/hw_sysctl.h"

// the headers to access the TivaWare Library
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"

#include "BITDEFS.H"

#define ALL_BITS (0xff<<2)

// **********************************************************************
// PROTOTYPES
static void SetLED(void);
static void UpdateTeam(void);

// READABILITY DEFINES

// ColorSwitch will be PB0
#define ColorSwitchHi 	BIT0HI
#define ColorSwitchLo 	BIT0LO

// GameLED PB1
#define GameLEDHi		BIT1HI
#define GameLEDLo		BIT1LO

// BlueTeam LED PB2
#define BlueTeamLEDHi	BIT2HI
#define BlueTeamLEDLo	BIT2LO

// RedGame LED PB3
#define RedTeamLEDHi 		BIT3HI
#define RedTeamLEDLo 		BIT3LO

// MODULE LEVEL VARIABLES
static uint8_t TeamColor; // 0 = Blue; 1 = Red
static uint8_t LastTeamColor;

// **********************************************************************
// PUBLIC FUNCTIONS //
// **********************************************************************

// Initializes all the hardware for communicating with switchs and LEDs
// related to game play and team color
void InitTeamColorAndGameLEDs(void)
{
	// set up port B by enabling the peripheral clock, waiting for the 
  	// peripheral to be ready for PB0, PB1, PB2 & PB3
 	HWREG(SYSCTL_RCGCGPIO) |= SYSCTL_RCGCGPIO_R1;
	while((HWREG(SYSCTL_PRGPIO)&SYSCTL_PRGPIO_R1) != SYSCTL_PRGPIO_R1);

	// Turn on Digital enable
	HWREG(GPIO_PORTB_BASE + GPIO_O_DEN) |= (ColorSwitchHi | GameLEDHi | BlueTeamLEDHi | RedTeamLEDHi);

	// Set the Switch to direction of input
	HWREG(GPIO_PORTB_BASE + GPIO_O_DIR) &= (ColorSwitchLo);
	// Set the LEDs to direction of output, and Set the directions to Output
	HWREG(GPIO_PORTB_BASE + GPIO_O_DIR) |= (GameLEDHi | BlueTeamLEDHi | RedTeamLEDHi);
	
  	// start with all LEDs off
	HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) &= (GameLEDLo | BlueTeamLEDLo | RedTeamLEDLo);
	
	// Init TeamColor to SwitchValue
	TeamColor = HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) & ColorSwitchHi;
	LastTeamColor = 0; // init the first time to 0 (arbitrary)

	// Set the LEDs correspondingly
	SetLED();
}

// Checks to see if the switch has gone off
bool CheckTeamColorSwitch(void)
{
  bool FoundSwitch = false;
	// Update reading
	UpdateTeam();

	// Check to see if it has changed
	if(TeamColor != LastTeamColor)
	{
    FoundSwitch = true;
		SetLED();
	}
  
  return FoundSwitch;
}

// Getter fxn for team color (0 = Blue) (1 = Red)
uint8_t GetTeamColor(void)
{
  if(TeamColor == 0)
  {
    return 1;
  }
  else
  {
    return 0;
  }

}

// Turns off GameLED
void GameLEDOff(void)
{
	HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) &= GameLEDLo;
}

// Turns on GameLED
void GameLEDOn(void)
{
	HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) |= GameLEDHi;
}

// **********************************************************************
// PRIVATE FUNCTIONS //
// **********************************************************************

// Updates the TeamColor and sets LEDColor Accordingly
static void UpdateTeam(void)
{
	LastTeamColor = TeamColor; // Save the value
	// Read in the value of the team color and change accordingly
   TeamColor = (HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) & ColorSwitchHi);
}

// Turns on the correct LEDs based upon the switch
static void SetLED(void)
{
	if(TeamColor == 0) // Blue
	{
		// RedTeamLEDOff
		HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) &= RedTeamLEDLo;

		// BlueTeamLEDOn
		HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) |= BlueTeamLEDHi;
	}
	else // Red
	{
		// BlueTeamLEDOff
		HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) &= BlueTeamLEDLo;

		// RedTeamLEDOn
		HWREG(GPIO_PORTB_BASE + (GPIO_O_DATA + ALL_BITS)) |= RedTeamLEDHi;
	}
}