/****************************************************************************
 Module
   HardwareInitialize.c

 Revision
   1.0.1

 Description
   This is a hardware initialization file for the ME218B project for Team 3.

 Notes

 History
 When           Who     What/Why
 -------------- ---     --------
 02/15/2019     bibit   created file
****************************************************************************/

/*----------------------------- Include Files -----------------------------*/
/* include header files for this state machine as well as any machines at the
   next lower level in the hierarchy that are sub-machines to this machine
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "HardwareInitialize.h"

#include "ES_Types.h"
#include "termio.h"
#include "BITDEFS.H"
#include <stdint.h>
#include <stdbool.h>

#include "inc/hw_pwm.h"
#include "inc/hw_gpio.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_nvic.h"
#include "inc/hw_ssi.h"
#include "inc/hw_Timer.h"

#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/pwm.h"

/*----------------------------- Module Defines ----------------------------*/
// Clock is 40MHz..with 32x prescaling that is 125 KHz
// 125 KHz is 1250000 ticks per second or 1250 ticks per milisecond
#define PWMTicksPerMS 1250

#define BitsPerNibble 4
#define PWM0_GenA_Normal (PWM_0_GENA_ACTCMPAU_ONE | PWM_0_GENA_ACTCMPAD_ZERO)
#define PWM0_GenB_Normal (PWM_0_GENB_ACTCMPBU_ONE | PWM_0_GENB_ACTCMPBD_ZERO)
#define PWM1_GenA_Normal (PWM_1_GENA_ACTCMPAU_ONE | PWM_1_GENA_ACTCMPAD_ZERO)
#define PWM1_GenB_Normal (PWM_1_GENB_ACTCMPBU_ONE | PWM_1_GENB_ACTCMPBD_ZERO)
#define PWM2_GenA_Normal (PWM_2_GENA_ACTCMPAU_ONE | PWM_2_GENA_ACTCMPAD_ZERO)

/*---------------------------- Module Functions ---------------------------*/
/* prototypes for private functions for this machine. They should be
   functions relevant to the behavior of this state machine.
*/
static void InitializeSPI(void);
static void InitializePWM(void);
static void InitializeInputCapture(void);
static void InitializeGPIO(void);

/*---------------------------- Module Variables ---------------------------*/
// everybody needs a state variable, you may need others as well.
// type of state variable should match htat of enum in header file

/*------------------------------ Module Code ------------------------------*/
//**************************************************************************/

/****************************************************************************
 Function
     InitializeHardware

 Parameters
     None

 Returns
     None

 Description
     Initializes all ports for ME218B Team 3's project.  The following are
     the assigned pins:

      PA2 - SPI SSI0Clk (Alt. No. 2) COMPASS communications
      PA3 - SPI SSI0Fss (Alt. No. 2) COMPASS communications
      PA4 - SPI SSI0Rx (Alt. No. 2) COMPASS communications
      PA5 - SPI SSI0Tx (Alt. No. 2) COMPASS communications

      PB2 - I2C I2C0SCL (Alt. No. 3) color sensor communication
      PB3 - I2C I2C0SPA (Alt. No. 3) color sensor communication

      PA6 - PWM M1PWM2 (Alt. No. 5) sorter servo
      PA7 - PWM M1PWM3 (Alt. No. 5) team selection servo
      PB4 - PWM M0PWM2 (Alt. No. 4) recycling bin servo
      PB5 - PWM M0PWM3 (Alt. No. 4) trash bin servo
      PB6 - PWM M0PWM0 (Alt. No. 4) left drive motor
      PB7 - PWM M0PWM1 (Alt. No. 4) right drive motor
      PD0 - PWM M1PWM0 (Alt. No. 5) IR recycling center

      PC4 - input capture WT0CCP0 (Alt. No. 7) left drive motor
      PC5 - input capture WT0CCP1 (Alt. No. 7) right drive motor
      PD1 - input capture WT2CCP1 (Alt. No. 7) beacon rear detection

      PB0 - GPIO output for left motor direction
      PB1 - GPIO output for right motor direction
      PE0 - GPIO input for front left limit switch
      PE1 - GPIO input for front right limit switch
      PE2 - GPIO input for rear left limit switch
      PE3 - GPIO input for rear right limit switch
      PE5 - GPIO input for team designation switch
      PF0 - GPIO output for conveyor belt motor
      PF1 - GPIO output for game started LED
      PF4 - GPIO input for tape sensor

 Notes


 Author
     Bibit Bianchini, 2/15/2019
****************************************************************************/
void InitializeHardware(void)
{
  // first enable the clocks to ports A, B, C, D, E, and F
  HWREG(SYSCTL_RCGCGPIO) |=
      (BIT0HI | BIT1HI | BIT2HI | BIT3HI | BIT4HI | BIT5HI);

  // wait for each of the peripherals to be ready
  // --> port A
  while ((HWREG(SYSCTL_PRGPIO) & BIT0HI) != BIT0HI)
  {}
  // --> port B
  while ((HWREG(SYSCTL_PRGPIO) & BIT1HI) != BIT1HI)
  {}
  // --> port C
  while ((HWREG(SYSCTL_PRGPIO) & BIT2HI) != BIT2HI)
  {}
  // --> port D
  while ((HWREG(SYSCTL_PRGPIO) & BIT3HI) != BIT3HI)
  {}
  // --> port E
  while ((HWREG(SYSCTL_PRGPIO) & BIT4HI) != BIT4HI)
  {}
  // --> port F
  while ((HWREG(SYSCTL_PRGPIO) & BIT5HI) != BIT5HI)
  {}

  // do all of the SPI initialization
  InitializeSPI();

  // do all of the I2C initialization
  // --> all of this is done in the I2CService initialization, so will not
  //     do this here.

  // do all of the PWM initialization
  InitializePWM();

  // do all of the input capture initialization
  InitializeInputCapture();

  // do all of the GPIO initialization
  InitializeGPIO();

  // globally enable interrupts
  __enable_irq();
}

/***************************************************************************
 private functions
 ***************************************************************************/
/****************************************************************************
 Function
     InitializeSPI

 Parameters
     None

 Returns
     None

 Description
     Initializes all SPI ports for ME218B Team 3's project.  The following
     are the assigned pins:

      PA2 - SPI SSI0Clk (Alt. No. 2) COMPASS communications
      PA3 - SPI SSI0Fss (Alt. No. 2) COMPASS communications
      PA4 - SPI SSI0Rx (Alt. No. 2) COMPASS communications
      PA5 - SPI SSI0Tx (Alt. No. 2) COMPASS communications

 Notes

 Author
     Bibit Bianchini, 2/15/2019
****************************************************************************/
static void InitializeSPI(void)
{
  // enable clock to SSI module 0
      HWREG(SYSCTL_RCGCSSI) |= SYSCTL_RCGCSSI_R0;

  // program GPIO for alternate functions
      HWREG(GPIO_PORTA_BASE + GPIO_O_AFSEL) |= (BIT2HI | BIT3HI | BIT4HI | BIT5HI);

  // write in GPIOCTL to select desired functions
      HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL) =
      (HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL) & 0xff0000ff) + (2 << BitsPerNibble * 2)
      + (2 << BitsPerNibble * 3) + (2 << BitsPerNibble * 4) + (2 << BitsPerNibble * 5);

  // program PA2, PA3, PA4, & PA5 for digital I/O
      HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= (BIT2HI | BIT3HI | BIT4HI | BIT5HI);

  // set PA2, PA3, & PA5 to be outputs
      HWREG(GPIO_PORTA_BASE + GPIO_O_DIR) |= (BIT2HI | BIT3HI | BIT5HI);
  // set PA4 to be an input
      HWREG(GPIO_PORTA_BASE + GPIO_O_DIR) &= (BIT4LO);

  // turn on the pull-up resistor for the clock line for SPI mode 3
      HWREG(GPIO_PORTA_BASE + GPIO_O_PUR) |= (BIT2HI);

  // wait for SSI0 to be ready
  while ((HWREG(SYSCTL_RCGCSSI) & SYSCTL_RCGCSSI_R0) != SYSCTL_RCGCSSI_R0)
  {}

  // disable SSI0 0
      HWREG(SSI0_BASE + SSI_O_CR1) &= (~SSI_CR1_SSE);

  // select Master mode, and TXRIS for End of Transmission
      HWREG(SSI0_BASE + SSI_O_CR1) &= (~SSI_CR1_MS);
      HWREG(SSI0_BASE + SSI_O_CR1) |= (SSI_CR1_EOT);

  // configure SSI clock source to be the system clock
      HWREG(SSI0_BASE + SSI_O_CC) = (SSI_CC_CS_SYSPLL);

  // configure clock prescaler (Bit Rate 15 kHz) Set CPSR to 132
      HWREG(SSI0_BASE + SSI_O_CPSR) =
      HWREG(SSI0_BASE + SSI_O_CPSR) & (0xFFFFFF00) + 132;
  // Set SCR to 19
      HWREG(SSI0_BASE + SSI_O_CR0) = ((HWREG(SSI0_BASE + SSI_O_CR0) + (60 << SSI_CR0_SCR_S)));

  // configure SPH = 1 because data is captured at the second edge
      HWREG(SSI0_BASE + SSI_O_CR0) |= SSI_CR0_SPH;

  // configure SPO = 1 because idle state is high
      HWREG(SSI0_BASE + SSI_O_CR0) |= SSI_CR0_SPO;

  // freescale SPI Mode
      HWREG(SSI0_BASE + SSI_O_CR0) = ((HWREG(SSI0_BASE + SSI_O_CR0) &
      (~SSI_CR0_FRF_M)) | SSI_CR0_FRF_MOTO);

  // set up sending 8 bit data between command generator & TIVA
      HWREG(SSI0_BASE + SSI_O_CR0) = ((HWREG(SSI0_BASE + SSI_O_CR0) &
      (~SSI_CR0_DSS_M)) | SSI_CR0_DSS_8);

  // locally enable interrupts (TXIM in SSIIM)
      HWREG(SSI0_BASE + SSI_O_IM) |= SSI_IM_TXIM;

  // enable SSI (DISABLING FOR ACTIVATING ON THE COMPASS MODULE ITSELF)
      HWREG(SSI0_BASE + SSI_O_CR1) |= (SSI_CR1_SSE);

  // enable NVIC bit 7 in EN0
      HWREG(NVIC_EN0) |= BIT7HI;

  // globally enable interrupts
  //__enable_irq(); // commented because this is done in InitializeHardware
}

/****************************************************************************
 Function
     InitializePWM

 Parameters
     None

 Returns
     None

 Description
     Initializes all PWM ports for ME218B Team 3's project.  The following
     are the assigned pins:

      PB6 - PWM M0PWM0 (Alt. No. 4) left drive motor
      PB7 - PWM M0PWM1 (Alt. No. 4) right drive motor

      PB4 - PWM M0PWM2 (Alt. No. 4) recycling bin servo
      PB5 - PWM M0PWM3 (Alt. No. 4) trash bin servo

      PD0 - PWM M1PWM0 (Alt. No. 5) IR recycling center

      PA6 - PWM M1PWM2 (Alt. No. 5) sorter servo
      PA7 - PWM M1PWM3 (Alt. No. 5) team selection servo

 Notes

 Author
     Bibit Bianchini, 2/15/2019
****************************************************************************/
static void InitializePWM(void)
{
  // start by enabling the clock to both PWM Modules (PWM0 & PWM1)
  HWREG(SYSCTL_RCGCPWM) |= (SYSCTL_RCGCPWM_R0 | SYSCTL_RCGCPWM_R1);

  // Select the PWM clock as System Clock/32 (this sets both modules)
  HWREG(SYSCTL_RCC) = (HWREG(SYSCTL_RCC) & ~SYSCTL_RCC_PWMDIV_M) |
      (SYSCTL_RCC_USEPWMDIV | SYSCTL_RCC_PWMDIV_32);

  // make sure that the PWM module clock has gotten going
  // --> module 0
  while ((HWREG(SYSCTL_PRPWM) & SYSCTL_PRPWM_R0) != SYSCTL_PRPWM_R0)
  {}
  // --> module 1
  while ((HWREG(SYSCTL_PRPWM) & SYSCTL_PRPWM_R1) != SYSCTL_PRPWM_R1)
  {}

  // disable the PWMs while initializing
  // --> module 0
  HWREG(PWM0_BASE + PWM_O_0_CTL) = 0;
  // --> module 1
  HWREG(PWM1_BASE + PWM_O_0_CTL) = 0;

  // program generators to go to 1 at rising compare A/B, 0 on falling
  // compare A/B
  HWREG(PWM0_BASE + PWM_O_0_GENA) = PWM0_GenA_Normal; // module 0 PWM 0
  HWREG(PWM0_BASE + PWM_O_0_GENB) = PWM0_GenB_Normal; // module 0 PWM 1
  HWREG(PWM0_BASE + PWM_O_1_GENA) = PWM1_GenA_Normal; // module 0 PWM 2
  HWREG(PWM0_BASE + PWM_O_1_GENB) = PWM1_GenB_Normal; // module 0 PWM 3
  HWREG(PWM1_BASE + PWM_O_0_GENA) = PWM0_GenA_Normal; // module 1 PWM 0
  HWREG(PWM1_BASE + PWM_O_1_GENA) = PWM1_GenA_Normal; // module 1 PWM 2
  HWREG(PWM1_BASE + PWM_O_1_GENB) = PWM1_GenB_Normal; // module 1 PWM 3

  /* ALL OF THESE PERIOD-SETTING AND ENABLING STEPS SHOULD HAPPEN IN
     INDIVIDUAL MODULES, NOT HERE:
// Set the PWM period. Since we are counting both up & down, we
// initialize the load register to 1/2 the desired total period. We
// will also program the match compare registers to 1/2 the desired
// high time
Period_0 = Startup_Period_ms * PWMTicksPerMS;
HWREG(PWM0_BASE + PWM_O_0_LOAD) = ((Period_0)) >> 1;

// Set the initial Duty cycle on A to 50% by programming the compare
// value to 1/2 the period to count up (or down). Technically, the
// value to program should be Period/2 - DesiredHighTime/2, but since
// the desired high time is 1/2 the period, we can skip the subtract
HWREG(PWM0_BASE + PWM_O_0_CMPA) = HWREG(PWM0_BASE + PWM_O_0_LOAD) >> 1;
// Set the initial Duty cycle on B to 50% like A
HWREG(PWM0_BASE + PWM_O_0_CMPB) = HWREG(PWM0_BASE + PWM_O_0_LOAD) >> 1;

// enable the PWM outputs
HWREG(PWM0_BASE + PWM_O_ENABLE) |= (PWM_ENABLE_PWM0EN | PWM_ENABLE_PWM1EN);

*/

  // now configure the pins to be PWM outputs
  // start by selecting the alternate functions for all pins
  HWREG(GPIO_PORTA_BASE + GPIO_O_AFSEL) |= (BIT6HI | BIT7HI);
  HWREG(GPIO_PORTB_BASE + GPIO_O_AFSEL) |= (BIT4HI | BIT5HI | BIT6HI | BIT7HI);
  HWREG(GPIO_PORTD_BASE + GPIO_O_AFSEL) |= BIT0HI;

  // now choose to map PWM to those pins, using the specified mux values
  // --> PA6 and PA7 with mux value 5
  HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL) =
      (HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL) & 0x00ffffff) +
      (5 << (6 * BitsPerNibble)) + (5 << (7 * BitsPerNibble));
  // --> PB4, PB5, PB6, and PA7 with mux value 4
  HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL) =
      (HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL) & 0x0000ffff) +
      (4 << (4 * BitsPerNibble)) + (4 << (5 * BitsPerNibble)) +
      (4 << (6 * BitsPerNibble)) + (4 << (7 * BitsPerNibble));
  // --> PD0 with mux value 5
  HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) =
      (HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) & 0xfffffff0) +
      (5 << (0 * BitsPerNibble));

  // enable all pins for digital I/O as digital outputs
  HWREG(GPIO_PORTA_BASE + GPIO_O_DEN) |= (BIT6HI | BIT7HI);
  HWREG(GPIO_PORTA_BASE + GPIO_O_DIR) |= (BIT6HI | BIT7HI);
  HWREG(GPIO_PORTB_BASE + GPIO_O_DEN) |= (BIT4HI | BIT5HI | BIT6HI | BIT7HI);
  HWREG(GPIO_PORTB_BASE + GPIO_O_DIR) |= (BIT4HI | BIT5HI | BIT6HI | BIT7HI);
  HWREG(GPIO_PORTD_BASE + GPIO_O_DEN) |= BIT0HI;
  HWREG(GPIO_PORTD_BASE + GPIO_O_DIR) |= BIT0HI;

  // set the up/down count mode, enable the PWM generator and make
  // both generator updates locally synchronized to zero count
  // --> PWM module 0, PWM0 + PWM1 (generator 0, A + B)
  HWREG(PWM0_BASE + PWM_O_0_CTL) = (PWM_0_CTL_MODE | PWM_0_CTL_ENABLE |
      PWM_0_CTL_GENAUPD_LS | PWM_0_CTL_GENBUPD_LS);
  // --> PWM module 0, PWM2 + PWM3 (generator 1, A + B)
  HWREG(PWM0_BASE + PWM_O_1_CTL) = (PWM_1_CTL_MODE | PWM_1_CTL_ENABLE |
      PWM_1_CTL_GENAUPD_LS | PWM_1_CTL_GENBUPD_LS);
  // --> PWM module 1, PWM0 (generator 0, A)
  HWREG(PWM1_BASE + PWM_O_0_CTL) = (PWM_0_CTL_MODE | PWM_0_CTL_ENABLE |
      PWM_0_CTL_GENAUPD_LS);
  // --> PWM module 1, PWM2 + PWM3 (generator 1, A + B)
  HWREG(PWM1_BASE + PWM_O_1_CTL) = (PWM_1_CTL_MODE | PWM_1_CTL_ENABLE |
      PWM_1_CTL_GENAUPD_LS | PWM_1_CTL_GENBUPD_LS);
}

/****************************************************************************
 Function
     InitializeInputCapture

 Parameters
     None

 Returns
     None

 Description
     Initializes all input capture ports for ME218B Team 3's project.  The
     following are the assigned pins:

      PC4 - input capture WT0CCP0 (Alt. No. 7) left drive motor
      PC5 - input capture WT0CCP1 (Alt. No. 7) right drive motor
      PD1 - input capture WT2CCP1 (Alt. No. 7) beacon rear detection

 Notes
     NVIC enabling should be done in more specific distributed places since
     some interrupts will not be necessary all the time (e.g. beacon
     detection, etc).

 Author
     Bibit Bianchini, 2/15/2019
****************************************************************************/
static void InitializeInputCapture(void)
{
  // enable the clock to the timers (Wide Timers 0 + 2)
  HWREG(SYSCTL_RCGCWTIMER) |= (SYSCTL_RCGCWTIMER_R0 | SYSCTL_RCGCWTIMER_R2);

  // wait for the peripherals to be ready
  // --> Wide Timer 0
  while ((HWREG(SYSCTL_PRWTIMER) & SYSCTL_RCGCWTIMER_R0) != SYSCTL_PRWTIMER_R0)
  {}
  // --> Wide Timer 2
  while ((HWREG(SYSCTL_PRWTIMER) & SYSCTL_RCGCWTIMER_R2) != SYSCTL_PRWTIMER_R2)
  {}

  // disable timers before configuring
  // --> wide timer 0, timers A + B
  HWREG(WTIMER0_BASE + TIMER_O_CTL) &= ~(TIMER_CTL_TAEN | TIMER_CTL_TBEN);
  // --> wide timer 2, timer B
  HWREG(WTIMER2_BASE + TIMER_O_CTL) &= ~TIMER_CTL_TBEN;

  // set up timer in 32-bit wide individual (not concatenated) mode
  // (don't get confused by the name of this constant -- 16 means individual)
  HWREG(WTIMER0_BASE + TIMER_O_CFG) = TIMER_CFG_16_BIT;
  HWREG(WTIMER2_BASE + TIMER_O_CFG) = TIMER_CFG_16_BIT;

  // initialize the Interval Load Register to 0xffff.ffff
  HWREG(WTIMER0_BASE + TIMER_O_TAILR) = 0xffffffff;
  HWREG(WTIMER0_BASE + TIMER_O_TBILR) = 0xffffffff;
  HWREG(WTIMER2_BASE + TIMER_O_TBILR) = 0xffffffff;

  // set up timers in capture mode (TAMR/TBMR=3, TAAMS/TBAMS=0), for edge
  //  time (TACMR/TBCMR=1), and for up-counting (TACDIR/TBCDIR=1)
  // --> wide timer 0, timer A
  HWREG(WTIMER0_BASE + TIMER_O_TAMR) =
      (HWREG(WTIMER0_BASE + TIMER_O_TAMR) & ~TIMER_TAMR_TAAMS) |
      (TIMER_TAMR_TACDIR | TIMER_TAMR_TACMR | TIMER_TAMR_TAMR_CAP);
  // --> wide timer 0, timer B
  HWREG(WTIMER0_BASE + TIMER_O_TBMR) =
      (HWREG(WTIMER0_BASE + TIMER_O_TBMR) & ~TIMER_TBMR_TBAMS) |
      (TIMER_TBMR_TBCDIR | TIMER_TBMR_TBCMR | TIMER_TBMR_TBMR_CAP);
  // --> wide timer 2, timer B
  HWREG(WTIMER2_BASE + TIMER_O_TBMR) =
      (HWREG(WTIMER2_BASE + TIMER_O_TBMR) & ~TIMER_TBMR_TBAMS) |
      (TIMER_TBMR_TBCDIR | TIMER_TBMR_TBCMR | TIMER_TBMR_TBMR_CAP);

  // set the event to rises only
  // --> wide timer 0, timers A + B
  HWREG(WTIMER0_BASE + TIMER_O_CTL) &=
      ~(TIMER_CTL_TAEVENT_M | TIMER_CTL_TBEVENT_M);
  // --> wide timer 2, timer B
  HWREG(WTIMER2_BASE + TIMER_O_CTL) &= ~TIMER_CTL_TBEVENT_M;

  // select the alternate functions for all pins
  HWREG(GPIO_PORTC_BASE + GPIO_O_AFSEL) |= (BIT4HI | BIT5HI);
  HWREG(GPIO_PORTD_BASE + GPIO_O_AFSEL) |= BIT1HI;

  // now choose to map input capture to those pins, using the specified mux
  // values
  // --> PC4 and PC5 with mux value 7
  HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) =
      (HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) & 0x0000ffff) +
      (7 << (4 * BitsPerNibble)) + (7 << (5 * BitsPerNibble));
  // --> PD1 with mux value 7
  HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) =
      (HWREG(GPIO_PORTD_BASE + GPIO_O_PCTL) & 0x00ff000f) +
      (7 << (1 * BitsPerNibble));

  // enable all pins for digital I/O as digital inputs
  HWREG(GPIO_PORTC_BASE + GPIO_O_DEN) |= (BIT4HI | BIT5HI);
  HWREG(GPIO_PORTC_BASE + GPIO_O_DIR) &= (BIT4LO & BIT5LO);
  HWREG(GPIO_PORTD_BASE + GPIO_O_DEN) |= BIT1HI;
  HWREG(GPIO_PORTD_BASE + GPIO_O_DIR) &= BIT1LO;

  // enable local capture interrupts for the timers
  // --> wide timer 0, timers A + B
  HWREG(WTIMER0_BASE + TIMER_O_IMR) |= (TIMER_IMR_CAEIM | TIMER_IMR_CBEIM);
  // --> wide timer 2, timer B
  HWREG(WTIMER2_BASE + TIMER_O_IMR) |= TIMER_IMR_CBEIM;

  // no NVIC initialization to occur in this function -- will be done in
  // individual modules.  example provided below:
  // example:  wide timer 0, timer A is interrupt 94, so is in EN2 at bit 30
  //HWREG(NVIC_EN2) |= BIT30HI; // commented out because individual modules
  // should determine when this happens -- not all input captures will be
  // enabled all the time.

  // enable the input capture timer
  // enable it to stall while stopped by the debugger
  // --> wide timer 0 timer A
  HWREG(WTIMER0_BASE + TIMER_O_CTL) |= (TIMER_CTL_TAEN | TIMER_CTL_TASTALL);
  // --> wide timer 0 timer B
  HWREG(WTIMER0_BASE + TIMER_O_CTL) |= (TIMER_CTL_TBEN | TIMER_CTL_TBSTALL);
  // --> wide timer 2 timer B
  HWREG(WTIMER2_BASE + TIMER_O_CTL) |= (TIMER_CTL_TBEN | TIMER_CTL_TBSTALL);
}

/****************************************************************************
 Function
     InitializeGPIO

 Parameters
     None

 Returns
     None

 Description
     Initializes all GPIO ports for ME218B Team 3's project.  The
     following are the assigned pins:

      PB0 - GPIO output for left motor direction
      PB1 - GPIO output for right motor direction
      PE0 - GPIO input for front left limit switch
      PE1 - GPIO input for front right limit switch
      PE2 - GPIO input for rear left limit switch
      PE3 - GPIO input for rear right limit switch
      PE5 - GPIO input for team designation switch
      PF0 - GPIO output for conveyor belt motor
      PF1 - GPIO output for game started LED
      PF4 - GPIO input for tape sensor

 Notes
     This does not read the initial state for inputs or set the first state
     for outputs.  All custom configuration will occur in the initialization
     functions for the modules which have control over these pins.

 Author
     Bibit Bianchini, 2/15/20197
****************************************************************************/
static void InitializeGPIO(void)
{
  // initialize PB0 & PB1 to be digital outputs
  HWREG(GPIO_PORTB_BASE + GPIO_O_DEN) |= (BIT0HI | BIT1HI);
  HWREG(GPIO_PORTB_BASE + GPIO_O_DIR) |= (BIT0HI | BIT1HI);

  // initialize PE0, PE1, PE2, PE3, & PE5 to be digital inputs
  HWREG(GPIO_PORTE_BASE + GPIO_O_DEN) |= (BIT0HI | BIT1HI | BIT2HI | BIT3HI | BIT5HI);
  HWREG(GPIO_PORTE_BASE + GPIO_O_DIR) &= (BIT0LO & BIT1LO & BIT2LO & BIT3LO & BIT5LO);

  // initialize PF4 to be a digital input
  HWREG(GPIO_PORTF_BASE + GPIO_O_DEN) |= BIT4HI;
  HWREG(GPIO_PORTF_BASE + GPIO_O_DIR) &= BIT4LO;

  // initialize PF0 & PF1 to be digital outputs
  HWREG(GPIO_PORTF_BASE + GPIO_O_DEN) |= (BIT0HI | BIT1HI);
  HWREG(GPIO_PORTF_BASE + GPIO_O_DIR) |= (BIT0HI | BIT1HI);
}

/*------------------------------- Footnotes -------------------------------*/
/*------------------------------ End of file ------------------------------*/