/* Main module */
/* By: Benjie Nelson, Nora Levinson, David Sirkin */
/* Dr. Von Sirlevson's Automated Locomotive Computation Engine */

/**************************************************/
/* Defines                                        */
/**************************************************/

#define MAIN


/**************************************************/
/* Includes                                       */
/**************************************************/

#include <timers12.h>

#include "ME218_E128.h"
#include "S12eVec.h"
#include "ADS12e.H"

#include "Main.h"
#include "Events.h"
#include "Navigation.h"
#include "StateMachine.h"
#include "GameDefs.h"
		    
/**************************************************/
/* Module Variables                               */
/**************************************************/

/* Store the current beacon DC and completed runs */

static unsigned int beaconDC;

static char completedRuns;

/**************************************************/
/* Initialization Functions                       */
/**************************************************/

/* Set E128 ports to accept inputs & send outputs */

void InitializePorts(void) {

  // Pin P0 is for FT bumper and pin P2 is FB bumper
  DDRP = BIT0LO & BIT2LO;
  PTP  = 0x00;

  // Pin S2 is for BL bumper and pin S3 is BR bumper
  DDRS = BIT2LO & BIT3LO;
  PTS  = 0x00;

 
  // Port T holds interrupts, pin T1 is flash detect
  DDRT = 0x00;
 
  // Port U holds PWM, pin U2 is H-bridge error flag
  DDRU = BIT2LO; 
  PTU  = 0x00;

  // Port AD holds tape sensors, 0=B, 1=L, 2=C & 3=R
  ADS12_Init ("OOAAAAAA");
}

/* Set PWM to 20KHz for Maxon and 400Hz for Hitec */

void InitializePWM(void) {

  PWME = BIT034HI;       // PWM enable channel 0,3,4
  
  PWMPRCLK = PRE_SCL;    // Pre-scale PWM by PRE_SCL

  PWMPOL   = BIT034HI;   // Set all active states HI

  PWMSCLA = PWM_SCA;     // Scale clock A by PWM_SCA

  PWMSCLB = PWM_SCB;     // Scale clock B by PWM_SCB
  PWMCLK  = BIT034HI;    // Apply scale clocks SA/SB


  PWMPER0 = PWM_PRA;     // Set channel 0 to PWM_PRA
  PWMPER3 = PWM_PRB;     // Set channel 3 to PWM_PRB

  PWMPER4 = PWM_PRA;     // Set channel 4 to PWM_PRA
  MODRR   = BIT034HI;    // Send to port U pin 0,3,4

}

/* Sense dispenser and goal beacon using an input */
/* capture interrupt on timer 0 channel 4, pin T0 */

void InitializeInterrupts(void) {
  EnableInterrupts;

  
  // Enable timer0 and scale the shared clock by 128
  TIM0_TSCR1 = _S12_TEN;
  TIM0_TSCR2 = _S12_PR2 | _S12_PR1 | _S12_PR0; 

  // Enable interrupt on channel TC4 & make it an IC

  TIM0_TIE |= _S12_C4I;
  TIM0_TIOS = 0x00;
  
  // Set the IC to identify rising and falling edges

  TIM0_TCTL3 |= _S12_EDG4A | _S12_EDG4B;
}
		  
/**************************************************/
/* Beacon IC Interrupt                            */
/**************************************************/

/* Find the interval since the last edge, set the */
/* period and determine the duty cycle. Only scan */
/* for a period around the beacon freq of 1.25KHz */

void interrupt _Vec_tim0ch4 GetBeaconDC(void) {

  static unsigned int interval, lastEdge;
  static unsigned int hiTime, loTime, period;

  interval = TIM0_TC4 - lastEdge;
  
  if(PTT & BIT0HI)

    loTime = interval;
  else
    hiTime = interval;

  
  period = hiTime + loTime;
  
  if(period > 100 && period < 215)

    beaconDC = (hiTime * 100) / period; 

  lastEdge = TIM0_TC4;

  TIM0_TFLG1 = _S12_C4F; 
  
  TMRS12_InitTimer(BEACON, LOST_BEACON);
}

/**************************************************/
/* Timing Functions                               */
/**************************************************/

/* Set timer (only 0-7) delay (only unsigned int) */

void SetTimer(char timer, unsigned int time) {

  TMRS12_InitTimer(timer, time);
}

/* Return whether the indicated timer has expired */

char Expired(char timer) {

  return(TMRS12_IsTimerExpired(timer) == TMRS12_EXPIRED);
}

/* Wait for specified delay time (provided in ms) */

void Wait(unsigned int time) {

  SetTimer(WAIT, time);
  while(!Expired(WAIT));
}

/**************************************************/
/* Main                                           */
/**************************************************/

#ifdef MAIN

/* Time-out the game at 2 minutes, or 120 seconds */

void main(void) {
  int i;

  
  InitializePorts();
  InitializePWM();
  InitializeInterrupts();
  TMRS12_Init(TMRS12_RATE_1MS);

  for(i = 0; i < 120; i++) {  
    SetTimer(GAME, 1000);

    
    while(!Expired(GAME))
      RunGameSM(CheckEvents());
  }
  Stop();
}

#endif