#include	"camtt.h"

#define		MOTOR_PERIOD		5	// Half the period in ms
#define		CW					0
#define		CCW					1
#define		PWR_CAL				710
#define		STRB1_CAL			32760L
#define		STRB2_CAL			32760L
#define		STRB3_CAL			32760L
#define		STRB4_CAL			32760L

enum {CHAN_CTRL, LINK_CTRL, MAX_COUNT, TRANS_COUNT, FINAL_TRANS_TIME, LAST_TRANS_TIME};

/* Host Service Request */
#define		Initialize		1

/* Host Sequence */
#define         SingleNoLinks		0
#define		ContinuousNoLinks	1
#define         SingleLinks		2
#define		ContinuousLinks		3

/* PAC Pin Action Control (input) */
#define         NoDetect	   	0x00
#define         DetRising               0x04
#define         DetFalling              0x08
#define         DetEither               0x0c
#define         NoChangePAC             0x10

/* TBS Time Base/Directionality Control */
#define         InputChan               0x00
#define         CapTCR1			0x00
#define         CapTCR2			0x40

/********************* Function Prototypes *******************/

void motor_step(int steps, int dir);
void	SetupTPUCount(short chan);
long	GetTPUCount(short chan);


/*********************** Global Variables *********************/



/*********************************************************************************
	main
*******************************************************************************/

void main(void)
{
	char charbuf[10];
	char adbuf[20];

	InitTT8(NO_WATCHDOG, TT8_TPU);   /* setup Model 8 for running C programs */
	TPUGetPin(0);					// Photo Mult. 1
	TPUGetPin(1);					// Photo Mult. 2
	TPUGetPin(2);				// Hall Sig.
  	TPUSetPin(3, 0);			// Mot Phase 1
  	TPUSetPin(4, 0);			// Mot Phase 2
  	TPUSetPin(5, 0);			// Strobe 4
  	TPUSetPin(6, 0);			// Strobe 3
  	TPUSetPin(7, 0);			// Strobe 2
  	TPUSetPin(8, 0);			// Strobe 1

  	PConfOutp(D,3);				// Motor Enable
  	PClear(D,3);
  	PConfOutp(D,4);				// Turn CPU off
  	PSet(D,4);
  	PConfOutp(D,5);				// Turn Camera off
  	PSet(D,5);

//*************** Setup TPU Counters for Photomults **************


	SetupTPUCount(1);

// ****************** Main Program Loop ***********************

	PutStr("\nH2O Camera Tattletale Program v1.0\n\n\n");

  	while(1)		// Wait for commands
  	{

		PutStr("\n\nEnter command: ");
		gets(charbuf);

		if(!strcmp(charbuf, "mot"))
		{
			motor_step(500, CW);
			motor_step(500, CCW);
		}

		else if(!strcmp(charbuf, "reset"))			ResetToMon();

		else if(!strcmp(charbuf, "strb1on"))		TPUSetPin(8,1);
		else if(!strcmp(charbuf, "strb2on"))		TPUSetPin(7,1);
		else if(!strcmp(charbuf, "strb3on"))		TPUSetPin(6,1);
		else if(!strcmp(charbuf, "strb4on"))		TPUSetPin(5,1);
		else if(!strcmp(charbuf, "strb1off"))		TPUSetPin(8,0);
		else if(!strcmp(charbuf, "strb2off"))		TPUSetPin(7,0);
		else if(!strcmp(charbuf, "strb3off"))		TPUSetPin(6,0);
		else if(!strcmp(charbuf, "strb4off"))		TPUSetPin(5,0);

		else if(!strcmp(charbuf, "cpuon"))			PClear(D,4);
		else if(!strcmp(charbuf, "cpuoff"))			PSet(D,4);
		else if(!strcmp(charbuf, "camon"))			PClear(D,5);
		else if(!strcmp(charbuf, "camoff"))			PSet(D,5);

		else if(!strcmp(charbuf, "pwr"))
			printf("\nPower = %6.2f V\n", (float)AtoDReadWord(0)/PWR_CAL);

		else if(!strcmp(charbuf, "strb1volt"))
			printf("\nStrobe 1 Volt = %7.2f V\n", (float)AtoDReadWord(1)/STRB1_CAL);

		else if(!strcmp(charbuf, "strb2volt"))
			printf("\nStrobe 2 Volt = %7.2f V\n", (float)AtoDReadWord(2)/STRB2_CAL);

		else if(!strcmp(charbuf, "strb3volt"))
			printf("\nStrobe 3 Volt = %7.2f V\n", (float)AtoDReadWord(3)/STRB3_CAL);

		else if(!strcmp(charbuf, "strb4volt"))
			printf("\nStrobe 4 Volt = %7.2f V\n", (float)AtoDReadWord(4)/STRB4_CAL);

		else if(!strcmp(charbuf, "hallsig"))
			printf("\nHall Sig. = %d\n", TPUGetPin(2));

		else if(!strcmp(charbuf, "pm1"))
		{
			SetupTPUCount(0);
			DelayMilliSecs(1000L);
			printf("\nPM1 count = %ld\n", GetTPUCount(0));
		}

		else if(!strcmp(charbuf, "pm2"))
		{
			SetupTPUCount(1);
			DelayMilliSecs(1000L);
			printf("\nPM2 count = %ld\n", GetTPUCount(1));
		}


		else	PutStr("\nWhat?");

    }

}	/* main() */


/***************************************************/

void motor_step(int steps, int dir)
{
	int step;

	if(dir)		// CW rotation
	{
		TPUSetPin(3, 0);	// Clear PH1
		TPUSetPin(4, 0);	// Clear PH2
		DelayMilliSecs(MOTOR_PERIOD);
		PSet(D,3);			// Turn motor driver on
		DelayMilliSecs(MOTOR_PERIOD);

		for(step=0; step<steps; step++)
		{
  			DelayMilliSecs(MOTOR_PERIOD);
			TPUSetPin(4, 1);	// Set PH2
	 		DelayMilliSecs(MOTOR_PERIOD);
	  		TPUSetPin(3, 1);	// Set PH1
	  		DelayMilliSecs(MOTOR_PERIOD);
	  		TPUSetPin(4, 0);	// Clear PH2
	  		DelayMilliSecs(MOTOR_PERIOD);
	  		TPUSetPin(3, 0);	// Clear PH1
		}
		PClear(D,3);			// Turn motor driver on
	}

	else		// CCW rotation
	{
		TPUSetPin(3, 0);	// Clear PH1
 		TPUSetPin(4, 0);	// Clear PH2
		DelayMilliSecs(MOTOR_PERIOD);
		PSet(D,3);			// Turn motor driver on
		DelayMilliSecs(MOTOR_PERIOD);

		for(step=0; step<steps; step++)
		{
	  		DelayMilliSecs(MOTOR_PERIOD);
			TPUSetPin(3, 1);	// Set PH1
	 		DelayMilliSecs(MOTOR_PERIOD);
	  		TPUSetPin(4, 1);	// Set PH2
	  		DelayMilliSecs(MOTOR_PERIOD);
	  		TPUSetPin(3, 0);	// Clear PH1
	  		DelayMilliSecs(MOTOR_PERIOD);
	  		TPUSetPin(4, 0);	// Clear PH2
		}
		PClear(D,3);		// Turn motor driver on
	}

}


//**************************************************************************
// Setup channel for count input
//**************************************************************************

void	SetupTPUCount(short chan){

	// SETUP CHANNEL
	TPUGetPin(chan);		//Set pin as input

	CHANPRIOR(chan,Disabled);
	*CISR ^= (1 << chan );		// Clear any pending interrupt
	*CIER &= ~(1 << chan);		// disable interrupt
	FUNSEL(chan,ITC);		// select input capture function

	PRAM[chan][CHAN_CTRL]	= DetRising;	// what to count (edges)
	PRAM[chan][LINK_CTRL]	= 0x0E;		// no links
	PRAM[chan][MAX_COUNT]	= 0xFFFF;	// maximum count

	HOSTSEQ(chan,ContinuousNoLinks); // continuous count, no links

	HOSTSERVREQ(chan,Initialize);	// init

	CHANPRIOR(chan,MiddlePrior);	// priority

	while(HOSTSERVSTAT(chan)&3) 	// poll until service ends (00)
		;

	}


//**************************************************************************
// Get current channel count
//**************************************************************************

long	GetTPUCount(short chan){

	// Poll Interrupt Bit to check for overflow
	if ( ((*CISR & (1 << chan )) != 0) )
	  {					// if overflow
	   *CISR ^= (1 << chan );		// Clear interrupt bit
	   PRAM[chan][TRANS_COUNT] = 0;	// reset count
	  }
	return(PRAM[chan][TRANS_COUNT]);	// get count
	}
