/* BENCHAM.C    v1.1

Changes since v1.0:
--Low power delay function "delay_lp()" added to reduce power consumption
  while running out of flash memory.
--Data cycle timing loop changed accomodate low power function.
--User EEPROM now functional due to updated (version 2) TT8 AZTEC-C
  library from Onset BBS.
--Motor functions now store error codes only when an error occurs to
  make data easier to read.
--"Running..." and "START" feedback added to allow central controller
  check for proper operation.
--Carriage returns added to end of strings to force printf() to output line.

*/

#include	"bcsys.h"

/********************* Function Prototypes *******************/

void bcinit(void);
void data_cycle(void);
void setup(void);
void cal_data_cycle(void);

/*********************** Global Variables *********************/

unsigned  g_stir_ticks, g_purge_ticks, g_slide_ticks;

ulong g_sample_sets = 3,
      g_sample_rate = 3,          /* Sets per day */
      g_flow_cell_delay = 5,  	/* Min */
      g_stir_speed = 9,        	/* RPM */
      g_flow_speed = 35,
      g_bccal_time = 50;       	/* Min */

struct calvar{
  short sample_sets;
  short sample_rate;
  short flow_cell_delay;
  short stir_speed;
  short flow_speed;
  short bccal_time;
} cv;


/*******************************************************************************
**	main
*******************************************************************************/
void main(void){
  char menukey;

#ifdef AZTEC_C
  InitTT8(NO_WATCHDOG, TT8_TPU);   /* setup Model 8 for running C programs */
#endif
  bcinit();
  printf("\nTT8 intialized\n");

  while(1){

    printf("\n\n\nBenthic Chamber Main Menu V1.1");
    printf("\n1 -- Test Functions");
    printf("\n2 -- Setup");
    printf("\n3 -- Data Cycle");
    printf("\n4 -- Offload Data");
    printf("\n5 -- Cal Data Cycle");
    printf("\n9 -- Reset");

    QueryChar("\n\nEnter Selection: ", '0', "123459", &menukey);


    switch(menukey){
      case '1':
	test_func();
	break;

      case '2':
	setup();
	break;

      case '3':
	data_cycle();
	break;

      case '4':
	offload_data();
	break;

      case '5':
	cal_data_cycle();
	break;

      case '9':
	bc_reset();
	break;
    }
  }


}	/* main() */

/***************************************************/

void bcinit(void){

#ifdef AZTEC_C
  int chan;
  static ExcCFrame      framebuf1, framebuf2, framebuf3;
  UeeErr err = 0;

  for(chan=0; chan<=12; chan++){
    TPUInterruptDisable(chan);
  }

  PConfOutp(D,3);  PClear(D,3);
  PConfOutp(D,4);  PClear(D,4);
  PConfOutp(D,5);  PClear(D,5);

  PConfOutp(E,0);  PClear(E,0);
  PConfOutp(E,1);  PClear(E,1);
  PConfInp(E,2);
  PConfOutp(E,3);  PClear(E,3);
  PConfOutp(E,4);  PSet(E,4);
  PConfOutp(E,5);  PSet(E,5);
  PConfOutp(E,6);  PClear(E,6);
  PConfOutp(E,7);  PClear(E,7);

  PConfOutp(F,2);  PClear(F,2);
  PConfOutp(F,4);  PClear(F,4);


  TPUSetPin(0,1);
  TPUGetPinES(1, DetRising);
  TPUGetPinES(2, DetRising);
  TPUGetPin(3);
  TPUGetPinES(4, DetRising);
  TPUGetPin(5);
  TPUSetPin(6,0);
  TPUSetPin(7,0);
  TPUSetPin(8,0);
  TPUSetPin(9,0);
  TPUSetPin(10,0);
  TPUSetPin(11,1);
  TPUSetPin(12,0);

/*** Setup Interrupt Handlers ***/

  InstallHandler(stir_turns, TPU_INT_VECTOR + STIR_TURNS_CHAN, &framebuf1);

  InstallHandler(purge_turns, TPU_INT_VECTOR + PURGE_TURNS_CHAN, &framebuf2);

  InstallHandler(slide_turns, TPU_INT_VECTOR + SLIDE_TURNS_CHAN, &framebuf3);



//  SetInterruptMask(ALL_RUPTS_MASK);


/*** Read UEEPROM ***/

  err = UeeReadBlock(0, (uchar *)&cv, (short) (sizeof(cv)) );
  if (err) printf("\n Error %d reading from UEEPROM \n", err);
  else printf("\nRead of UEEPROM successful\n");

  g_sample_sets = cv.sample_sets;
  g_sample_rate = cv.sample_rate;
  g_flow_cell_delay = cv.flow_cell_delay;
  g_stir_speed = cv.stir_speed;
  g_flow_speed = cv.flow_speed;
  g_bccal_time = cv.bccal_time;

  SerShutDown(FALSE, FALSE);    /* Shut down MAX242 to save power */
#endif

/*** Misc. Initializations ***/

  file_init();            	/* Initialize File System */
  SimSetFSys(320000);           /* Slow down system clock */
  SerSetBaud(9600, 0);          /* Reset the baud rate */


}

/*************************************************/

void setup(void){
  char menukey;
  UeeErr err;

  SimSetFSys(16e6);       /* Full speed to make UEEPROM work */
  SerSetBaud(9600, 0);

  do{
    SerInFlush();
    printf("\n\n\n1 -- Set Date/Time");
    printf("\n2 -- Set Mission Parameters");
    printf("\n3 -- Set Calibration Parameters");
    printf("\n9 -- Exit");
    QueryChar("\n\nEnter Selection", '9', "123456789", &menukey);

    switch(menukey){
      case '1':
	SetDateTime();
	break;

      case '2':         /* Mission Parameters */

	QueryNum("\nEnter Sample Sets: ", "%lu", "%lu", &g_sample_sets);
	QueryNum("\nEnter Sample Rate (sets/day): ", "%lu", "%lu", &g_sample_rate);
	QueryNum("\nEnter Flow Cell Delay (min): ", "%lu", "%lu", &g_flow_cell_delay);
	QueryNum("\nEnter Flow Pump Speed (10-80): ", "%lu", "%lu", &g_flow_speed);
	QueryNum("\nEnter Stir Speed (RPM): ", "%lu", "%lu", &g_stir_speed);
	QueryNum("\nEnter BC Cal Time (min): ", "%lu", "%lu", &g_bccal_time);

	cv.sample_sets = (short)g_sample_sets;
	cv.sample_rate = (short)g_sample_rate;
	cv.flow_cell_delay = (short)g_flow_cell_delay;
	cv.stir_speed = (short)g_stir_speed;
	cv.flow_speed = (short)g_flow_speed;
	cv.bccal_time = (short)g_bccal_time;

	/*** Write UEEPROM ***/

	err = UeeWriteBlock( 0, (uchar *) &cv, 12 );
	if (err)
	  printf("\n Error %d writing to UEEPROM\n", err);
	else
	  printf("\n Write of UEEPROM sucessful\n", err);
	break;

      case '3':

	break;
    }
  } while(menukey != '9');
  SimSetFSys(320000);
  SerSetBaud(9600, 0);
}


/***************************************************/

void data_cycle(void){
  short chan, err = 0;
  ulong sample = 0, sample_time, next_sample_time, sample_period;

  printf("\nRunning...\n");

  sample_period = 86400/g_sample_rate;   /* Period in secs */
  clear_mem();            		/* Clear the data memory */

  delaysecs(1);
  purge_valve(OPEN);
  delaysecs(1);
  purge_valve(CLOSE);     		/* Close Purge Valve */
  delaysecs(1);
  stir_motor(ON);          		/* Start Stir Motor */
  next_sample_time = time(0);

  while(1){

    err = slide_valve(AMBIENT);
    if(!err) flow_pump_on();	  	/* Calibrate O2 cell */
    delaymins(g_flow_cell_delay);
    store_data(FLOW_CELL_AMBIENT);
    delaysecs(1);
    flow_pump_off();
    delaysecs(1);

    err = slide_valve(CHAMBER);
    if(!err) flow_pump_on();   		/* Measure chamber O2 */
    delaymins(g_flow_cell_delay);
    store_data(FLOW_CELL_CHAMBER);
    delaysecs(1);
    flow_pump_off();
    delaysecs(1);

    err = slide_valve(AMBIENT);
    if(!err) flow_pump_on();	  	/* Calibrate O2 cell */
    delaymins(g_flow_cell_delay);
    store_data(FLOW_CELL_AMBIENT);
    delaysecs(1);
    flow_pump_off();

    sample++;
    if( sample >= g_sample_sets ) break;

    next_sample_time += sample_period;
    printf("\nDelay time start...\n");
    while( time(0) <= next_sample_time ){  /* Hang out till next sample set*/
      delay_lp();
    }
  }

  stir_motor(OFF);
  purge_valve(OPEN);
  return;

}  /* End data_cycle() */

/********************************************************/

void cal_data_cycle(void){
  int x;
  ulong delay_time;

  printf("\nRunning...\n");

  delay_time = (g_bccal_time*60)/4;

  clear_mem();            		/* Clear the data memory */
  stir_motor(ON);
  delaysecs(1);

  for(x=0;x<4;x++){
    store_data(CAL_DATA);
    delaysecs(delay_time);
  }

  stir_motor(OFF);
  return;
}