/***********************GLOBAL DECLARATIONS AND INITS************************/
#if ROM == 1
#nodebug     
#endif
#use "kdm.lib"
#use "serial.lib"
#use "default.h"
#use "rtk.lib"
#use "modem232.lib"

char Verify_Check_Sum();

#define PROM_SIZE	256			/* 27C020 prom */
#define hstate1  0x05			/* hex values to home injector motor */
#define hstate2  0x04
#define hstate3  0x06
#define hstate4  0x02
#define hstate5  0x0A
#define hstate6  0x08
#define hstate7  0x09
#define hstate8  0x01

#define state1  0x05				/* hex values to step injector motor */
#define state2  0x06
#define state3  0x0A
#define state4  0x09

#define up     1					/* needle movement direction & m510 flowrate */
#define down   2
#define stop	3
#define home   4

#define KEYPAD_SIZE 		16        /* 16 key keypad */
#define LK_COLS     		20        /* 20 column lcd display */
#define LK_LINES     	 4        /* 4 line lcd display */
#define BOTTOM_PAGE  	 6        /* first diag page */
#define TOP_PAGE    		11        /* last diag page, increase this number to 
                                 	 add more pages! */
#define SET_TOP     		15
#define SET_BOTTOM  		12
#define PASS         	1
#define FAIL         	0
#define YES          	1        /* YES */            
#define NO     			0        /* NO */
#define INPUT  			1        /* flag for page type */
#define OUTPUT       	0        /* flag for page type */
#define DKPASS    		52
#define DKFAIL   	   	53
#define DCPASS   	   	54
#define DCMINFAIL 		55
#define DCMAXFAIL 		56
#define SWPASS    		57
#define SWFAIL    		58
#define BPRESS_FAIL		59
#define TSENSOR_FAIL		60
#define BSENSOR_FAIL		61
#define B_TOP_SEAL_FAIL 62
#define B_TOP_SEAL_FAIL2 63
#define RAMP_FAIL			64
#define AZRAMP_FAIL		65
#define CHK_COUNT_HI    66
#define CHK_COUNT_LO		67
#define CHK_COUNT_PASS	68
#define COMPLETE     	69

#define STOPPED         0       /* these are status words for the test process */
#define RUNNING         1        
#define PRESSURIZING    2        
#define WAITING         3 
#define ERROR           4
#define HOMEING		   5
#define ABORT			   6
#define NEEDLEWASH	   7
#define IDLE			   8
#define PRIME			   9
#define PRIMING		  10
#define WASH			  11
#define WASHING		  12
#define PURGE			  13
#define PURGING		  14
#define NPURGE			  15
#define NPURGING		  16
#define HOME			  17
#define NEEDLEWASHING  18
#define END_DECAY		  19
#define END_DCOUNT	  20
#define END_SWIDTH	  21
#define BACKPRESSURE   22
#define BPRESSURIZING  23
#define RPURGE			  24
#define RPURGING		  25
#define DCOUNTING 	  26
#define SWIDTHING		  27
#define TOP_ADJUST	  28
#define TOP_SENSOR	  29
#define B_TOP_SEAL	  30
#define SYS_COMPLIANCE 31
#define AUTO_ZERO		  32
#define AZPRESSURIZING 33
#define AZWAITING      34
#define AZRUNNING      35 
#define AZDKPASS		  36
#define AZDKFAIL		  37
#define AZEND_DECAY	  38
#define READY			  39
#define CHK_COUNT		  40
#define END_CHK_COUNT  41
#define OTHER			  42

shared char curkey;                 /* holds value of key press */
shared char hout;                   /* holds data byte of hi-volt port */
shared char old_day;                /* last day */
shared char old_sec;                /* last sec */
shared char keybuf[12];             /* holds data from kbd untill enter is pressed */

shared int loc;                     /* keeps track of cursor location on display */
shared int is_it_in;                /* is all needed data entered into keybuf? */
shared int indx;                    /* keeps track of menu item highlited on a page*/
shared int lcd_buzy;						/* don't write to display if buzy */
shared int diagflg;                 /* flag is set when in the diag mode*/
shared int functflg;                /* flag is set when test/abort/diag is pressed*/
shared int access_ok;               /* set if access to diags is ok*/
shared int caldue;                  /* calibration is due now! */
shared int caldate[3];              /* holds the cal due date read from eeprom */
shared int leak_time;					/* test decay time */
shared int sys_up;                  /* is the system up and running(init done?) */
shared int error;                   /* error flag */
shared int setup;                   /* flag for setup mode */
shared int azero;							/* do system compliance ? */
shared int dncount_min;					/* minimum Down Count specification */
shared int dncount_max;					/* maximum Down Count specification */
shared int swcount;						/* seal width specification */
shared int dkspec;						/* uut decay specification */
shared int azdkspec;						/* system decay specification */
shared int pressr;						/* test pressure */
shared int flow;   						/* holds current flowrate */
shared int flow_set;   					/* sets flowrate */
shared int injector;						/* injector status */
shared int down_count;					/* keeps track of down count */
shared int seal_count;					/* keeps track of seal count */
shared int step_count;					/* keeps track of motor steps */
shared int check_count;					/* keeps track of motor steps */
shared float pres[2];               /* holds pressure readings */

shared unsigned long ticker;        /* clock value in seconds since the begining of time */
shared unsigned long calwhen;       /* long representation of cal due date */

char maxtime[] = {"24"};            /* to check validity of time entered */
char maxday[] = {"12"};             /* to check validity of date entered */
char state[] = {state1,state2,state3,state4};
char hstate[] = {hstate1,hstate2,hstate3,hstate4,hstate5,hstate6,hstate7,hstate8};

int stepstate;
int hstepstate;
int tab_keys[] = {'C','7','4','1','0','8','5','2',
                  'F','9','6','3','E','D','T','A'}; /* key table for keypad */

/****************************STRUCTURE FOR PAGES*****************************/
shared struct PAGE
{
 char line[4][22];               /* struct for 4 line  display messages */
 char cursor_pos[9][10]; 
 int min_width;
 int max_width;
 int page_type;
 char cursor_type[6];
} page[63];
/************************STRUCTURE FOR SET UP STATUS*************************/
shared struct SETUP_STATUS
{
 int dcountmax;
 int dcountmin;
 int decay;
 int pressr;
 int ready;
 int swidth;
}setup_status;
/************************STRUCTURE FOR STATUS/CONTROL************************/
shared struct PTEST
{
   unsigned long start_time;       /*test start_time*/
   int status;                     /*pressurizing,decay,stopped,homeing?*/
   int result;                     /*pass or fail*/
   int abort;
   float start_press;              /*starting pressure*/
   float end_press;                /*finished pressure*/
   float decay_press;              /*pressure decay */
   float azdecay_press;				  /*system decay*/
}ptest;             

/***********************STRUCTURE FOR REAL TIME CLOCK************************/

shared struct tm dt[2];

/***********************STRUCTURE FOR REAL TIME KERNEL***********************/
int task0(),task1(),task2(),task3(),task4(),task5(),task6(),backgnd();
int (*Ftask[]) ()={task0,task1,task2,task3,task4,task5,task6,backgnd};

#define TASKSIZE_STORE 100
#define NTASKS 8
#define TASK0 0
#define TASK1 1                /*tasks and priorities. read the book! */
#define TASK2 2
#define TASK3 3
#define TASK4 4
#define TASK5 5    
#define TASK6 6    
#define BACKGND 7
#define RUNKERNEL 1

/****************************END GLOBAL DECLARATIONS*************************/
root main()
{
 int i,z;
 /* start tasks, every n ticks, launch program here */

    outport(DCNTL,0x30);
    setdaisy ( 3 );          	/* setup KIO daisy chain */
    DI();                    	/* disable interrupts */
    sys_up = NO;
    lk_init_keypad();        	/* initialize keypad/display/kernel*/
    lk_loadtab(tab_keys, sizeof(tab_keys));   /*load above declared key table*/
    lk_settab(1);                             /*set the table (kdm.lib)*/
    run_every(TASK0,10);     	/* run task 0 every 10 ticks */
    run_every(TASK1,20);    	/* run task 1 every 20 ticks */
    run_every(TASK2,30);    	/* run task 2 every 30 ticks */
    run_every(TASK3,40);     	/* run task 3 every 40 ticks */
    run_every(TASK4,50);     	/* run task 4 every 50 ticks */
    run_every(TASK6,200);    	/* run task 6 every 500 ticks */
    run_cancel(TASK5);       	/* cancel task 5 until diagnostics are entered  */
   
    struct_init();                  /* init structures */
    sys_init();
    if(ROM == 1)
      {
       show_page(61);
       if(!Verify_Check_Sum())
         {
          while(1)
          {
          show_page(62);
          }
         }
      }    
                         /* init system */
    sys_up = YES;
    EI();									/* enable interrupts */
           for(i=0; i<400; i++);
          {
           for(z=0; z<6800; z++);
          }

    show_page(indx = 1);				/* show setup(17) page or start(1) page*/
    backgnd();                    	/* TURN THIS THING LOOSE */
}

/********************************struct_init()*******************************/
/************************INITIALIZE SYSYTEM STRUCTURESS**********************/
struct_init()
{
 sprintf(page[0].line[0], "   T.E. #  82503    "); 
 sprintf(page[0].line[1], " SEALPACK/INJECTOR  "); 
 sprintf(page[0].line[2], " CALIBRATION DUE ON ");
 sprintf(page[0].line[3], "      %02d/%02d/%02d      ",
                           caldate[0],caldate[1],caldate[2]);
 page[0].page_type = OUTPUT;
 sprintf(page[0].cursor_type,"\x1b0");

 sprintf(page[1].line[0], "   READY FOR TEST   "); 
 sprintf(page[1].line[1], "                    "); 
 sprintf(page[1].line[2], "PRESS START TO BEGIN"); 
 sprintf(page[1].line[3], " Test Software 4.0  "); // Test software version here 
 page[1].page_type = OUTPUT;
 sprintf(page[1].cursor_type,"\x1b0");

 sprintf(page[2].line[0],"CONNECT UUT, REMOVE ");
 sprintf(page[2].line[1],"OBJECTS FROM NEEDLE ");
 sprintf(page[2].line[2],"PATH & PRESS 'ENTER'");
 sprintf(page[2].line[3],"TO INITIATE TEST.   ");
 page[2].page_type = OUTPUT;
 sprintf(page[2].cursor_type,"\x1b0");
    
 sprintf(page[3].line[0]," THIS TEST HAS BEEN ");
 sprintf(page[3].line[1],"STOPPED! FIX PROBLEM");
 sprintf(page[3].line[2],"& RETEST OR CONNECT ");
 sprintf(page[3].line[3],"A NEW UNIT FOR TEST.");
 page[3].page_type = OUTPUT;
 sprintf(page[3].cursor_type,"\x1b0");

 sprintf(page[4].line[0]," KEY-IN THE CORRECT ");
 sprintf(page[4].line[1],"NUMERIC CODE TO GAIN");
 sprintf(page[4].line[2],"ACCESS TO DIAGNOSTIC");
 sprintf(page[4].line[3],"UTILITIES ->        ");
 page[4].page_type = INPUT;
 sprintf(page[4].cursor_type,"\x1bb");
 sprintf(page[4].cursor_pos[0],"\x1bp314");
 sprintf(page[4].cursor_pos[1],"\x1bp315");
 sprintf(page[4].cursor_pos[2],"\x1bp316");
 sprintf(page[4].cursor_pos[3],"\x1bp317");
 page[4].min_width = 4;   
 page[4].max_width = 4;

 sprintf(page[5].line[0],"USE THE UP-ARROW AND");
 sprintf(page[5].line[1],"THE DOWN-ARROW KEYS ");
 sprintf(page[5].line[2]," TO SCROLL THRU THE ");
 sprintf(page[5].line[3],"SETUP UTILITIES MENU");
 page[5].page_type = OUTPUT;
 sprintf(page[5].cursor_type,"\x1b0");

 sprintf(page[6].line[0],"BATTERY BACKED CLOCK");
 sprintf(page[6].line[1],"TIME SETTING UTILITY");
 sprintf(page[6].line[2],"THE CURRENT TIME IS ");
 sprintf(page[6].line[3],"      %02d:%02d:%02d      ", 
                           dt[0].tm_hour, dt[0].tm_min,dt[0].tm_sec); 
 page[6].page_type = INPUT;
 sprintf(page[6].cursor_type,"\x1bb");
 sprintf(page[6].cursor_pos[0],"\x1bp306");
 sprintf(page[6].cursor_pos[1],"\x1bp307");
 sprintf(page[6].cursor_pos[2],"\x1bp309");
 sprintf(page[6].cursor_pos[3],"\x1bp310");
 sprintf(page[6].cursor_pos[4],"\x1bp312");
 sprintf(page[6].cursor_pos[5],"\x1bp313");
 page[6].min_width = 6;   
 page[6].max_width = 6;
                                 
 sprintf(page[7].line[0],"BATTERY BACKED CLOCK");
 sprintf(page[7].line[1],"DATE SETTING UTILITY");
 sprintf(page[7].line[2],"THE CURRENT DATE IS ");
 sprintf(page[7].line[3],"     %02d/%02d/%d     ",dt[0].tm_mon,dt[0].tm_mday,dt[0].tm_year+1900);
 page[7].page_type = INPUT;
 sprintf(page[7].cursor_type,"\x1bb");
 sprintf(page[7].cursor_pos[0],"\x1bp305");
 sprintf(page[7].cursor_pos[1],"\x1bp306");
 sprintf(page[7].cursor_pos[2],"\x1bp308");
 sprintf(page[7].cursor_pos[3],"\x1bp309");
 sprintf(page[7].cursor_pos[4],"\x1bp311");
 sprintf(page[7].cursor_pos[5],"\x1bp312");
 sprintf(page[7].cursor_pos[6],"\x1bp313");
 sprintf(page[7].cursor_pos[7],"\x1bp314");
 page[7].min_width = 8;   
 page[7].max_width = 8;
                   
 sprintf(page[8].line[0],"CALIBRATION DUE DATE");
 sprintf(page[8].line[1],"   SET-UP UTILITY   ");
 sprintf(page[8].line[2]," CALIBRATION DUE ON ");
 sprintf(page[8].line[3],"     %02d/%02d/%d     ",caldate[0],caldate[1],caldate[2]+1900);
 page[8].page_type = INPUT;
 sprintf(page[8].cursor_type,"\x1bb");
 sprintf(page[8].cursor_pos[0],"\x1bp305"); // MM
 sprintf(page[8].cursor_pos[1],"\x1bp306"); // MM
 sprintf(page[8].cursor_pos[2],"\x1bp308"); // DD
 sprintf(page[8].cursor_pos[3],"\x1bp309"); // DD
 sprintf(page[8].cursor_pos[4],"\x1bp311"); // YY
 sprintf(page[8].cursor_pos[5],"\x1bp312"); // YY
 sprintf(page[8].cursor_pos[6],"\x1bp313"); // YY
 sprintf(page[8].cursor_pos[7],"\x1bp314"); // YY
 page[8].min_width = 8;   
 page[8].max_width = 8;
 
 sprintf(page[9].line[0], "    #1 TRANSDUCER   "); 
 sprintf(page[9].line[1], " CONNECT PORT #2 TO "); 
 sprintf(page[9].line[2], " PRESSURE SOURCE.   "); 
 sprintf(page[9].line[3], "PRESSURE =      PSI "); 
 page[9].page_type = OUTPUT;
 sprintf(page[9].cursor_type,"\x1b0");
 
 sprintf(page[10].line[0], "    #2 TRANSDUCER   "); 
 sprintf(page[10].line[1], " CONNECT PORT #1 TO "); 
 sprintf(page[10].line[2], " PRESSURE SOURCE.   "); 
 sprintf(page[10].line[3], "PRESSURE =      PSI "); 
 page[10].page_type = OUTPUT;
 sprintf(page[10].cursor_type,"\x1b0");

 sprintf(page[11].line[0], "  SHOP AIR SWITCH   "); 
 sprintf(page[11].line[1], " CONNECT AIR SOURCE "); 
 sprintf(page[11].line[2], "    TO 'AIR IN'.    "); 
 sprintf(page[11].line[3], "PRESSURE =   60 PSI "); 
 page[11].page_type = OUTPUT;
 sprintf(page[11].cursor_type,"\x1b0");

 sprintf(page[12].line[0],"ENTER MIN # OF STEPS");
 sprintf(page[12].line[1]," FOR STREAM COUNT,  ");
 sprintf(page[12].line[2],"THEN PRESS 'ENTER'. ");
 sprintf(page[12].line[3],"MINIMUM COUNT =     ");
 page[12].page_type = INPUT;
 sprintf(page[12].cursor_type,"\x1bb");
 sprintf(page[12].cursor_pos[0],"\x1bp316");
 sprintf(page[12].cursor_pos[1],"\x1bp317");
 sprintf(page[12].cursor_pos[2],"\x1bp318");
 sprintf(page[12].cursor_pos[3],"\x1bp319");
 page[12].min_width = 1;   
 page[12].max_width = 4;

 sprintf(page[13].line[0],"ENTER MAX # OF STEPS");
 sprintf(page[13].line[1]," FOR STREAM COUNT,  ");
 sprintf(page[13].line[2],"THEN PRESS 'ENTER'. ");
 sprintf(page[13].line[3],"MAXIMUM COUNT =     ");
 page[13].page_type = INPUT;
 sprintf(page[13].cursor_type,"\x1bb");
 sprintf(page[13].cursor_pos[0],"\x1bp316");
 sprintf(page[13].cursor_pos[1],"\x1bp317");
 sprintf(page[13].cursor_pos[2],"\x1bp318");
 sprintf(page[13].cursor_pos[3],"\x1bp319");
 page[13].min_width = 1;   
 page[13].max_width = 4;
 
 sprintf(page[14].line[0]," KEY-IN DECAY SPEC  ");
 sprintf(page[14].line[1],"NEEDED FOR THIS TEST");
 sprintf(page[14].line[2],"THEN PRESS 'ENTER'  ");
 sprintf(page[14].line[3]," DECAY SPEC =       ");
 page[14].page_type = INPUT;
 sprintf(page[14].cursor_type,"\x1bb");
 sprintf(page[14].cursor_pos[0],"\x1bp314");
 sprintf(page[14].cursor_pos[1],"\x1bp315");
 sprintf(page[14].cursor_pos[2],"\x1bp316");
 sprintf(page[14].cursor_pos[3],"\x1bp317");
 page[14].min_width = 1;   
 page[14].max_width = 4;

 sprintf(page[15].line[0]," KEY-IN PRESSURE    ");
 sprintf(page[15].line[1],"NEEDED FOR THIS TEST");
 sprintf(page[15].line[2],"THEN PRESS 'ENTER'  ");
 sprintf(page[15].line[3],"  PRESSURE =        ");
 page[15].page_type = INPUT;
 sprintf(page[15].cursor_type,"\x1bb");
 sprintf(page[15].cursor_pos[0],"\x1bp313");
 sprintf(page[15].cursor_pos[1],"\x1bp314");
 sprintf(page[15].cursor_pos[2],"\x1bp315");
 sprintf(page[15].cursor_pos[3],"\x1bp316");
 page[15].min_width = 1;
 page[15].max_width = 4;

 sprintf(page[16].line[0], "NO OR LOW SHOP AIR!!"); 
 sprintf(page[16].line[1], "CHECK THE AIR SOURCE"); 
 sprintf(page[16].line[2], "IT SHOULD BE SET FOR"); 
 sprintf(page[16].line[3], "A MINIMUM OF 60 PSI "); 
 page[16].page_type = OUTPUT;
 sprintf(page[16].cursor_type,"\x1b0");

 sprintf(page[17].line[0],"PRESS SETUP TO ENTER");
 sprintf(page[17].line[1],"THE TEST PARAMETERS.");
 sprintf(page[17].line[2],"WHEN FINISHED PRESS ");
 sprintf(page[17].line[3]," 'CLEAR' TO RETURN. ");
 page[17].page_type = OUTPUT;
 sprintf(page[17].cursor_type,"\x1b0");

 sprintf(page[18].line[0]," MAKE SURE GRADUATE ");
 sprintf(page[18].line[1],"IS IN PLACE, THEN   ");
 sprintf(page[18].line[2],"PRESS ENTER TO PRIME");
 sprintf(page[18].line[3],"NEEDLE WASH TUBING. ");
 page[18].page_type = OUTPUT;
 sprintf(page[18].cursor_type,"\x1b0");

 sprintf(page[19].line[0]," MAKE SURE GRADUATE ");
 sprintf(page[19].line[1],"IS EMPTY & IN PLACE.");
 sprintf(page[19].line[2]," WHEN READY, PRESS  ");
 sprintf(page[19].line[3],"  'ENTER' TO TEST.  ");
 page[19].page_type = OUTPUT;
 sprintf(page[19].cursor_type,"\x1b0");

 sprintf(page[20].line[0],"GRADUATE SHOULD HAVE");
 sprintf(page[20].line[1],"A MINIMUM OF 1.25 ML");
 sprintf(page[20].line[2],"PRESS 'ENTER' KEY TO");
 sprintf(page[20].line[3]," CONTINUE TESTING.  ");
 page[20].page_type = OUTPUT;
 sprintf(page[20].cursor_type,"\x1b0");

 sprintf(page[21].line[0],"      PRIMING       ");
 sprintf(page[21].line[1],"        THE         ");
 sprintf(page[21].line[2],"    NEEDLE WASH     ");
 sprintf(page[21].line[3],"      TUBING.       ");
 page[21].page_type = OUTPUT;
 sprintf(page[21].cursor_type,"\x1b0");

 sprintf(page[22].line[0],"      RUNNING       ");
 sprintf(page[22].line[1],"                    ");
 sprintf(page[22].line[2],"  NEEDLE WASH TEST  ");
 sprintf(page[22].line[3],"                    ");
 page[22].page_type = OUTPUT;
 sprintf(page[22].cursor_type,"\x1b0");
 
 sprintf(page[23].line[0],"                    ");
 sprintf(page[23].line[1]," - PURGING NEEDLE - ");
 sprintf(page[23].line[2],"                    ");
 sprintf(page[23].line[3],"                    ");
 page[23].page_type = OUTPUT;
 sprintf(page[23].cursor_type,"\x1b0");
 
 sprintf(page[24].line[0],"                    ");
 sprintf(page[24].line[1],"     - PURGING -    ");
 sprintf(page[24].line[2],"   SYSTEM & U.U.T.  ");
 sprintf(page[24].line[3],"                    ");
 page[24].page_type = OUTPUT;
 sprintf(page[24].cursor_type,"\x1b0");

 sprintf(page[25].line[0],"                    ");
 sprintf(page[25].line[1]," - HOMING INJECTOR -");
 sprintf(page[25].line[2],"                    ");
 sprintf(page[25].line[3],"                    ");
 page[25].page_type = OUTPUT;
 sprintf(page[25].cursor_type,"\x1b0");

 sprintf(page[26].line[0],"                    ");
 sprintf(page[26].line[1],"  - NEEDLE DOWN -   ");
 sprintf(page[26].line[2],"                    ");
 sprintf(page[26].line[3],"                    ");
 page[26].page_type = OUTPUT;
 sprintf(page[26].cursor_type,"\x1b0");

 sprintf(page[27].line[0], "   OVER PRESSURE!!  "); 
 sprintf(page[27].line[1], "SYSTEM PRESSURE HAS "); 
 sprintf(page[27].line[2], "GONE OVER 6000 PSI. "); 
 sprintf(page[27].line[3], "CHECK FOR BLOCKAGES."); 
 page[27].page_type = OUTPUT;
 sprintf(page[27].cursor_type,"\x1b0");
 
 sprintf(page[28].line[0], " THE TESTER IS NOW  "); 
 sprintf(page[28].line[1], "RAMPING TO      PSI ");
 sprintf(page[28].line[2], "TO PERFORM THE DECAY"); 
 sprintf(page[28].line[3], "PORTION OF TEST.    "); 
 page[28].page_type = OUTPUT;
 sprintf(page[28].cursor_type,"\x1b0");
 
 sprintf(page[29].line[0], " DECAY TEST RUNNING "); 
 sprintf(page[29].line[1], "                    "); 
 sprintf(page[29].line[2], "TIME REMAINING      "); 
 sprintf(page[29].line[3], "PRESSURE =      PSI "); 
 page[29].page_type = OUTPUT;
 sprintf(page[29].cursor_type,"\x1b0");

 sprintf(page[30].line[0], "      !PASSED!      "); 
 sprintf(page[30].line[1], " DECAY SPEC IS      "); 
 sprintf(page[30].line[2], "      !PASSED!      "); 
 sprintf(page[30].line[3], " DECAY =      PSI   "); 
 page[30].page_type = OUTPUT;
 sprintf(page[30].cursor_type,"\x1b0");
 
 sprintf(page[31].line[0], "      !FAILED!      "); 
 sprintf(page[31].line[1], " DECAY SPEC IS      "); 
 sprintf(page[31].line[2], "      !FAILED!      "); 
 sprintf(page[31].line[3], " DECAY =      PSI   "); 
 page[31].page_type = OUTPUT;
 sprintf(page[31].cursor_type,"\x1b0");
 
 sprintf(page[32].line[0], " STREAM COUNT TEST  "); 
 sprintf(page[32].line[1], "      !PASSED!      "); 
 sprintf(page[32].line[2], "      !PASSED!      "); 
 sprintf(page[32].line[3], "STREAM COUNT IS     "); 
 page[32].page_type = OUTPUT;
 sprintf(page[32].cursor_type,"\x1b0");
 
 sprintf(page[33].line[0], "STREAM COUNT FAILED!"); 
 sprintf(page[33].line[1], " MINIMUM COUNT IS   "); 
 sprintf(page[33].line[2], "                    "); 
 sprintf(page[33].line[3], "STREAM COUNT IS     "); 
 page[33].page_type = OUTPUT;
 sprintf(page[33].cursor_type,"\x1b0");
 
 sprintf(page[34].line[0], "  SEAL WIDTH TEST   "); 
 sprintf(page[34].line[1], "      !PASSED!      "); 
 sprintf(page[34].line[2], "      !PASSED!      "); 
 sprintf(page[34].line[3], "SEAL COUNT IS       "); 
 page[34].page_type = OUTPUT;
 sprintf(page[34].cursor_type,"\x1b0");
 
 sprintf(page[35].line[0], " SEAL WIDTH FAILED! "); 
 sprintf(page[35].line[1], "   2690 MIN is 60   ");
 sprintf(page[35].line[2], "    717 MIN is 50   "); 
 sprintf(page[35].line[3], "SEAL COUNT IS       "); 
 page[35].page_type = OUTPUT;
 sprintf(page[35].cursor_type,"\x1b0");

 sprintf(page[36].line[0], " INCREASING FLOW TO "); 
 sprintf(page[36].line[1], " BUILD BACKPRESSURE "); 
 sprintf(page[36].line[2], "FOR STREAM COUNT AND "); 
 sprintf(page[36].line[3], " SEAL WIDTH TESTS.  "); 
 page[36].page_type = OUTPUT;
 sprintf(page[36].cursor_type,"\x1b0");
 
 sprintf(page[37].line[0], " -- STREAM COUNT -- "); 
 sprintf(page[37].line[1], "MINIMUM COUNT =     "); 
 sprintf(page[37].line[2], "MAXIMUM COUNT =     "); 
 sprintf(page[37].line[3], " COUNT =      STEPS "); 
 page[37].page_type = OUTPUT;
 sprintf(page[37].cursor_type,"\x1b0");
 
 sprintf(page[38].line[0], "  -- SEAL WIDTH --  "); 
 sprintf(page[38].line[1], "   2690 MIN is 60   "); 
 sprintf(page[38].line[2], "    717 MIN is 50   "); 
 sprintf(page[38].line[3], "  COUNT =     STEPS "); 
 page[38].page_type = OUTPUT;
 sprintf(page[38].cursor_type,"\x1b0");

 sprintf(page[39].line[0], "                    "); 
 sprintf(page[39].line[1], "  PURGING THROUGH   "); 
 sprintf(page[39].line[2], "    RESTRICTOR.     "); 
 sprintf(page[39].line[3], "                    "); 
 page[39].page_type = OUTPUT;
 sprintf(page[39].cursor_type,"\x1b0");

 sprintf(page[40].line[0], "STREAM COUNT FAILED!"); 
 sprintf(page[40].line[1], " MAXIMUM COUNT =    "); 
 sprintf(page[40].line[2], "                    "); 
 sprintf(page[40].line[3], "STREAM COUNT IS     "); 
 page[40].page_type = OUTPUT;
 sprintf(page[40].cursor_type,"\x1b0");

 sprintf(page[41].line[0], " !FAILED! TO REACH  "); 
 sprintf(page[41].line[1], "BACKPRESSURE.'ENTER'"); 
 sprintf(page[41].line[2], "TO RETEST OR 'START'"); 
 sprintf(page[41].line[3], "TO TEST NEW U.U.T.  "); 
 page[41].page_type = OUTPUT;
 sprintf(page[41].cursor_type,"\x1b0");

 sprintf(page[42].line[0], " !FAILED! DIDN'T SEE"); 
 sprintf(page[42].line[1], "TOP SENSOR.CHECK UUT"); 
 sprintf(page[42].line[2], "CONNECTIONS. PRESS  "); 
 sprintf(page[42].line[3], "START TO TEST AGAIN."); 
 page[42].page_type = OUTPUT;
 sprintf(page[42].cursor_type,"\x1b0");

 sprintf(page[43].line[0], " !FAILED! DIDN'T SEE"); 
 sprintf(page[43].line[1], "BOTTOM SENSOR. CHECK"); 
 sprintf(page[43].line[2], " CONNECTIONS. PRESS "); 
 sprintf(page[43].line[3], "START TO TEST AGAIN."); 
 page[43].page_type = OUTPUT;
 sprintf(page[43].cursor_type,"\x1b0");

 sprintf(page[44].line[0], "  TO RETEST U.U.T.  "); 
 sprintf(page[44].line[1], "   PRESS 'ENTER'.   "); 
 sprintf(page[44].line[2], "TO TEST A NEW U.U.T."); 
 sprintf(page[44].line[3], "   PRESS 'START'.   "); 
 page[44].page_type = OUTPUT;
 sprintf(page[44].cursor_type,"\x1b0");

 sprintf(page[45].line[0], " CONNECT 'NEEDLE' & "); 
 sprintf(page[45].line[1], "'SEAL PACK' TUBES TO"); 
 sprintf(page[45].line[2], "T ON INJECTOR STAND,"); 
 sprintf(page[45].line[3], " THEN PRESS 'ENTER'."); 
 page[45].page_type = OUTPUT;
 sprintf(page[45].cursor_type,"\x1b0");

 sprintf(page[46].line[0], "ADJUST SENSOR SO IT "); 
 sprintf(page[46].line[1], "SWITCHES OFF TO ON, "); 
 sprintf(page[46].line[2], "THEN PRESS 'ENTER'. "); 
 sprintf(page[46].line[3], "TOP SENSOR IS      ."); 
 page[46].page_type = OUTPUT;
 sprintf(page[46].cursor_type,"\x1b0");

 sprintf(page[47].line[0], " !FAILED!  COULDN'T "); 
 sprintf(page[47].line[1], "FIND BOTTOM OF TOP  "); 
 sprintf(page[47].line[2], "SEAL                "); 
 sprintf(page[47].line[3], "START TO TEST AGAIN."); 
 page[47].page_type = OUTPUT;
 sprintf(page[47].cursor_type,"\x1b0");

 sprintf(page[48].line[0], "RAMPING TO      PSI,"); 
 sprintf(page[48].line[1], "TO PERFORM A DECAY  ");
 sprintf(page[48].line[2], "TEST ON THE TESTER &"); 
 sprintf(page[48].line[3], "EXTERNAL TUBING.    "); 
 page[48].page_type = OUTPUT;
 sprintf(page[48].cursor_type,"\x1b0");
 
 sprintf(page[49].line[0], " DECAY TEST RUNNING "); 
 sprintf(page[49].line[1], "                    "); 
 sprintf(page[49].line[2], "TIME REMAINING      "); 
 sprintf(page[49].line[3], "PRESSURE =      PSI "); 
 page[49].page_type = OUTPUT;
 sprintf(page[49].cursor_type,"\x1b0");

 sprintf(page[50].line[0], " AUTO ZERO COMPLETE "); 
 sprintf(page[50].line[1], " DECAY SPEC IS      "); 
 sprintf(page[50].line[2], "      !PASSED!      "); 
 sprintf(page[50].line[3], " DECAY =      PSI   "); 
 page[50].page_type = OUTPUT;
 sprintf(page[50].cursor_type,"\x1b0");
 
 sprintf(page[51].line[0], " AUTO ZERO COMPLETE "); 
 sprintf(page[51].line[1], " DECAY SPEC IS      "); 
 sprintf(page[51].line[2], "      !FAILED!      "); 
 sprintf(page[51].line[3], " DECAY =      PSI   "); 
 page[51].page_type = OUTPUT;
 sprintf(page[51].cursor_type,"\x1b0");
 
 sprintf(page[52].line[0], "      PURGING       "); 
 sprintf(page[52].line[1], "        FOR         "); 
 sprintf(page[52].line[2], "  SYSTEM DECAY TEST "); 
 sprintf(page[52].line[3], "                    "); 
 page[52].page_type = OUTPUT;
 sprintf(page[52].cursor_type,"\x1b0");
 
 sprintf(page[53].line[0], "STEPPING MOTOR DOWN,"); 
 sprintf(page[53].line[1], "   TO LOCATE THE    "); 
 sprintf(page[53].line[2], "      BOTTOM OF     "); 
 sprintf(page[53].line[3], "    THE TOP SEAL.   "); 
 page[53].page_type = OUTPUT;
 sprintf(page[53].cursor_type,"\x1b0");
 
 sprintf(page[54].line[0], "      !FAILED!      "); 
 sprintf(page[54].line[1], "DIDN'T START IN TOP "); 
 sprintf(page[54].line[2], "SEAL.               "); 
 sprintf(page[54].line[3], "START TO TEST AGAIN."); 
 page[54].page_type = OUTPUT;
 sprintf(page[54].cursor_type,"\x1b0");

 sprintf(page[55].line[0], "      !FAILED!      "); 
 sprintf(page[55].line[1], " COULDN'T REACH SET "); 
 sprintf(page[55].line[2], " PRESSURE FOR DECAY."); 
 sprintf(page[55].line[3], "START TO TEST AGAIN."); 
 page[55].page_type = OUTPUT;
 sprintf(page[55].cursor_type,"\x1b0");

 sprintf(page[56].line[0], "                    "); 
 sprintf(page[56].line[1], " AIR WAS DETECTED IN"); 
 sprintf(page[56].line[2], "  THE INLET BUBBLE  "); 
 sprintf(page[56].line[3], "      SENSOR!       "); 
 page[56].page_type = OUTPUT;
 sprintf(page[56].cursor_type,"\x1b0");
 
 sprintf(page[57].line[0], "CHECKING FOR CORRECT"); 
 sprintf(page[57].line[1], " SENSOR ADJUSTMENT. "); 
 sprintf(page[57].line[2], "                    "); 
 sprintf(page[57].line[3], "DOWN COUNT IS       "); 
 page[57].page_type = OUTPUT;
 sprintf(page[57].cursor_type,"\x1b0");

 sprintf(page[58].line[0], "DOWN COUNT TOO LOW! "); 
 sprintf(page[58].line[1], " MINIMUM COUNT IS 36");
 sprintf(page[58].line[2], " ADJUST SENSORS UP  "); 
 sprintf(page[58].line[3], " DOWN COUNT WAS     "); 
 page[58].page_type = OUTPUT;
 sprintf(page[58].cursor_type,"\x1b0");

 sprintf(page[59].line[0], "DOWN COUNT TOO HIGH!"); 
 sprintf(page[59].line[1], " MAXIMUM COUNT IS 44");
 sprintf(page[59].line[2], "ADJUST SENSORS DOWN "); 
 sprintf(page[59].line[3], " DOWN COUNT WAS     "); 
 page[59].page_type = OUTPUT;
 sprintf(page[59].cursor_type,"\x1b0");

 sprintf(page[60].line[0], " ALL TESTS COMPLETE "); 
 sprintf(page[60].line[1], "      !PASSED!      "); 
 sprintf(page[60].line[2], "      !PASSED!      "); 
 sprintf(page[60].line[3], " DOWN COUNT WAS     "); 
 page[60].page_type = OUTPUT;
 sprintf(page[60].cursor_type,"\x1b0");
 
 sprintf(page[61].line[0], "   CHECK SUM TEST   "); 
 sprintf(page[61].line[1], "                    "); 
 sprintf(page[61].line[2], "   VERIFYING EPROM  "); 
 sprintf(page[61].line[3], "                    "); 
 page[61].page_type = OUTPUT;
 sprintf(page[61].cursor_type,"\x1b0");
 
 sprintf(page[62].line[0], "       ERROR!       "); 
 sprintf(page[62].line[1], "CHECKSUM TEST FAILED"); 
 sprintf(page[62].line[2], "                    "); 
 sprintf(page[62].line[3], "   CALL TEST ENG.   "); 
 page[62].page_type = OUTPUT;
 sprintf(page[62].cursor_type,"\x1b0");

 loadcaldate(page[8].line[3]); /*load the cal-due date from EEprom*/
 show_page(0);			            // display tester name and number
 lk_setbeep(300);
 chk_clock(page[6].line[3],page[7].line[3]);
 chkcal();      					 /* check when calibration is due */
return;
}
/****************************************************************************/
/**********************************sys_init()********************************/
/************************INITIALIZE SYSYTEM FUNCTIONS************************/
anymem sys_init()
{
outport(PIOCA, 0xcf);       // parallel port A control register mode 3
outport(PIOCA, 0x00);       // all bits output */
outport(PIODA, 0x00);		 // set output to zero (motor off)
outport(PIOCB, 0xcf);       // parallel port B control register mode 3
outport(PIOCB, 0x7f);       // bit 8 is output, all other bits & 

hv_enb();                   // enable hi volt outputs
hv_wr(0x00);                // valves and vacuum pump off
stepstate = 0;					 // set motor step sequence to zero
outport(CTC2,3);            // reset CTC2 (stop m510 pump)
loc = 0;
is_it_in  = NO;
error     = NO;
functflg  = NO;
diagflg   = NO;
access_ok = NO;
caldue    = NO;
injector  = NO;
lcd_buzy  = NO;
ticker = 0;
indx   = 1; 
curkey = 0x00;
hout   = 0;
old_day = dt[0].tm_mday - 1;              
old_sec = dt[0].tm_sec - 1; 
ticker = clock();
cleanbufr(keybuf,sizeof(keybuf));

flow = 255;
azdkspec = 660;
ptest.status = STOPPED;
ptest.abort  = WAITING;
ptest.result = WAITING;
leak_time = 180;
 
setup_status.dcountmin = NO;
setup_status.dcountmax = NO;
setup_status.swidth = NO;
setup_status.decay  = NO;
setup_status.pressr = NO;
setup_status.ready  = NO;

setup = NO;					// Yes to run Setup
azero = YES;

pressr = 4500;
dkspec = 270;
dncount_min = 50;
dncount_max = 126;
swcount = 50;
				
if(!IBIT(PIODB,5)) 		// Testing 717 seal pack
  {
   dncount_min = 50;
   dncount_max = 126;
   pressr = 4500;
   dkspec = 270;
  }
if(!IBIT(PIODB,6) && IBIT(PIODB,5))		// Testing 2690 Injectors
  {
   dncount_min = 85;
   dncount_max = 125;				// changed limits from (62-104) to (85-125) 2/19/2018
   pressr = 5000;
   dkspec = 270;
   swcount = 60;						// changed from (64) to (60) 2/20/2018
  }
down_count = 0;
seal_count = 0;
step_count = 0;
check_count = 0;
return;    
}     
/****************************************************************************/
/**********************************task0()***********************************/
/*************POSITIONS MOTOR ON UUT AND STARTS TIMER FOR TESTS****************/

indirect task0()
{
int z;
if(!sys_up || setup)return;

	if(ptest.status == TOP_SENSOR)
	  {
		nup(seal_count + down_count);  				// Move needle back to start, then
		if(!IBIT(PIODB,5) && !IBIT(PIODB,6))		// Testing 717 Injectors
		  {
		   ndown((down_count/2) + 10);				// put in middle of stream + 10 steps(10 steps 3/26/98)
		   mpump(flow_set = 0);							// stop pump
	    	c_valve(1);
	    	c_valve(2);
	    	c_valve(3);
		  }
		else
		  {
		   ndown(down_count/2);						// (12/09/05)
		  }
	   show_page(indx = 46);
	   ptest.status = TOP_ADJUST;
	  }

else if(ptest.status == HOME)needle_home();
     
else if(ptest.status == NEEDLEWASH)needle_wash();
    
else if(ptest.status == PRIME)
      {
		 show_page(indx = 21);			// Priming needle wash tubing
       o_valve(4);
       vpump(YES);
       ptest.start_time = ticker;
       ptest.status = PRIMING;
      }   
else if(ptest.status == WASH)
      {
       show_page(22);					// Needle Wash Test Running
       o_valve(4);
       vpump(YES);
       ptest.start_time = ticker;
       ptest.status = WASHING;
      }   
else if(ptest.status == NPURGE)
      {
       show_page(23);					// Purging Needle
       c_valve(1);
       c_valve(2);
       o_valve(3);
       mpump(flow_set = 30);
       ptest.start_time = ticker;
       ptest.status = NPURGING;
      }   
else if(ptest.status == PURGE)
      {
       show_page(indx = 24);			// Purging system and uut
       ptest.start_time = ticker;
       ptest.status = PURGING;
      }   

else if(ptest.status == PRESSURIZING)
      {
       show_page(indx = 28);						// ramping up to set psi
       lk_printf("\x1bp111%4d",pressr);
       c_valve(1);
       c_valve(2);
       ptest.start_time = ticker;
       ptest.status = WAITING;
       }

else if(ptest.status == AZPRESSURIZING)
      {
       show_page(indx = 48);						// ramping up to set psi
       lk_printf("\x1bp011%4d",pressr);
       c_valve(1);
       c_valve(2);
       ptest.start_time = ticker;
       ptest.status = AZWAITING;
       }
         
else if(ptest.status == RPURGE)
      {
		 needle_wash();
		 needle_home();
		  if(!IBIT(PIODB,6) && IBIT(PIODB,5))	// 2690 injectors
         {
          nup(200);									// make sure port's in top seal		
         }
        else
        {
		   nup(230);      							// make sure port's in top seal
		  } 
       show_page(39);								// Purging through restrictor
       if(!IBIT(PIODB,5))
         {
          ndown(94);                      	// 717 injector or seal pack
         }
       if(!IBIT(PIODB,6) && IBIT(PIODB,5))	// 2690 injectors
         {
          ndown(15);									// make sure port's in the middle of top seal(was 65 for old inj.)
         }
       o_valve(2);									// connect restrictor
       c_valve(3);
       o_valve(1);
       mpump(flow_set = 55);
       ptest.start_time = ticker;
       ptest.status = RPURGING;
      }

else if(ptest.status == BACKPRESSURE)
      {
       show_page(indx = 36);					// building back pressure
       c_valve(3);
       c_valve(1);
       mpump(flow_set = 115);					// start pump about .5 ml
  		 ptest.status = BPRESSURIZING;
     	}

else if(ptest.status == SYS_COMPLIANCE)
      {
		 o_valve(1);
       o_valve(2);
       o_valve(3);
    	 show_page(indx = 52);					// purging for auto zero
    	 mpump(flow_set = 30);
       ptest.start_time = ticker;
    	 ptest.status = AUTO_ZERO;    	 		    
     	}
return;
}
/****************************************************************************/
/**********************************task1()***********************************/
/**************** RUNS DECAY,DOWN COUNT, & SEAL WIDTH TESTS *****************/
indirect task1()
{
int sec,min;
if(!sys_up || setup)return;
  if(ptest.status == RUNNING)
    {
	  if(!lcd_buzy)show_page(indx = 29);								// decay test message
	  lcd_buzy = YES;
     sec = (((leak_time + ptest.start_time) - ticker) % 60);
     min = (((leak_time + ptest.start_time) - ticker) / 60);
     chk_volts(0);
     if(!functflg)
		 {
        lk_printf("\x1bp214%2d:%02d",min,sec);						// time remaining update
        lk_printf("\x1bp311%4d",(int)pres[0]);						// pressure udate
       }
     if((ticker - ptest.start_time) >= leak_time)
       {
        chk_volts(0);
        ptest.end_press = pres[0];
        ptest.decay_press = (ptest.start_press - ptest.end_press) - ptest.azdecay_press;
        vent_press();
        if(ptest.decay_press <= dkspec || ptest.decay_press <= 0)
          {
			  if(ptest.decay_press < 0)ptest.decay_press = 0;          
           ptest.result = DKPASS;
          }
        else
          {
           ptest.result = DKFAIL;
          }
        lcd_buzy = NO;
        ptest.start_time = ticker;	 									// sart timer for message display    
        ptest.status = END_DECAY;
       }
    }
else if(ptest.status == AZRUNNING)
    {
	  if(!lcd_buzy)show_page(indx = 49);								// decay test message
	  lcd_buzy = YES;
     sec = (((leak_time + ptest.start_time) - ticker) % 60);
     min = (((leak_time + ptest.start_time) - ticker) / 60);
     chk_volts(0);
     if(!functflg)
		 {
        lk_printf("\x1bp214%2d:%02d",min,sec);				// time remaining update
        lk_printf("\x1bp311%4d",(int)pres[0]);				// pressure udate
       }
     if((ticker - ptest.start_time) >= leak_time)
       {
        chk_volts(0);
        ptest.end_press = pres[0];
        ptest.azdecay_press = ptest.start_press - ptest.end_press;
        vent_press();
        if(ptest.azdecay_press <= azdkspec)					// system decay
          {
           ptest.result = AZDKPASS;
          }
        else
          {
           ptest.result = AZDKFAIL;
          }
        lcd_buzy = NO;
        ptest.start_time = ticker;	 							// sart timer for message display    
        ptest.status = AZEND_DECAY;
       }
    }
    
else if(ptest.status == B_TOP_SEAL)
	 {
	  if(!lcd_buzy)
	  	 {
	  	  wait100(4);
	  	  chk_volts(1);
	  	  if(pres[1] > 100)					                  // Is needle in top seal?
	  	 {
	  	  mpump(flow_set = 0);
	  	  ptest.result = B_TOP_SEAL_FAIL2;						// error! didn't start in top seal
		  ptest.status = OTHER;
		 }
		else
		 {
	     show_page(indx = 53);			      				  	// finding bottom of top seal
	  	  lcd_buzy = YES;
	  	  wait100(5);
	  	 }
	  	}
	  chk_volts(1);
	  if(pres[1] < 100)					                    	// wait until  needle comes out bottom of top seal
	  	 {
	  	  ndown(1);
	  	  wait100(3);
	  	  step_count = step_count + 1;	  						// add 1 to step count
	  	  if(step_count > 150)
	  	  	 {
	  	  	  mpump(flow_set = 0);
	  	  	  ptest.result = B_TOP_SEAL_FAIL;					// error! couldn't find stream
		     ptest.status = OTHER;
			 }
		 } 
	  else
	  	 {
         down_count = 0;					// reset down_count
         seal_count = 0;					// reset seal count
         step_count = 0;					// reset step_count
         lcd_buzy = NO;
         ptest.status = DCOUNTING;
        }
    }       	
else if(ptest.status == DCOUNTING)
    {
	  if(!lcd_buzy)
	    {
	     show_page(indx = 37);					// display down count test
	     ndown(down_count = dncount_min - 6);	// move down the minimum steps first
	    }
	  lcd_buzy = YES;
	  lk_printf("\x1bp116%3d",dncount_min);
	  lk_printf("\x1bp216%3d",dncount_max);
	  lk_printf("\x1bp309%3d",down_count);
	  
	  chk_volts(1);								// read #2 transducer
  	  if(pres[1] > 50)
		 {
		  o_valve(1);								// relieve pressure
		  wait100(6);
		  ndown(2);									// step injector 2 steps
		  down_count = down_count + 2;		// add 2 to down count
		  step_count = step_count + 2;		// add 2 to step count
		  c_valve(1);								// let pressure build
		  wait100(10);
		 }
	  else
	  	 {
	  	  if(down_count < dncount_min)
	  	    {
	  	     mpump(flow_set = 0);
	  	     ptest.result = DCMINFAIL;
	  	    }
	  	  if(down_count > dncount_max)
	  	  	 {
			  mpump(flow_set = 0);
	  	  	  ptest.result = DCMAXFAIL;
	  	  	 }
	  	  if(down_count >= dncount_min && down_count <= dncount_max)ptest.result = DCPASS;
	  	  lcd_buzy = NO;
        ptest.start_time = ticker;	 	// sart timer for message display    
	  	  ptest.status = END_DCOUNT;
	  	 }  
	 }
else if(ptest.status == SWIDTHING)
	 {
	  if(!lcd_buzy)
	    {
	     show_page(indx = 38);	 			// display seal width test
	     ndown(seal_count = 44);			// move down the minimum steps first
	  	 }
	  lcd_buzy = YES;
	  lk_printf("\x1bp310%3d",seal_count);
	  c_valve(1);
	  o_valve(3);
	  wait100(2);
	  chk_volts(1);							// read # 2 transducer
	  if(pres[1] > 50)
		 {
		  ndown(2);								// step injector 2 steps
		  seal_count = seal_count + 2;	// add 2 to seal count
		  step_count = step_count + 2;	// add 2 to step count
		 }
	  else
	  	 {
	  	 if(IBIT(PIODB,6))		        	// Testing anything but 2690 Injectors
	  	  {
	  	   mpump(flow_set = 0);
	  	  }
	  	  if(seal_count >= swcount)
	  	    {
	  	     ptest.result = SWPASS;	  	     
	  	    }
	  	   else
	  	    {
	  	     mpump(flow_set = 0);
	  	     ptest.result = SWFAIL;
	  	    }
	  	  lcd_buzy = NO;  
	  	  ptest.start_time = ticker;	 	// sart timer for message display    
	  	  ptest.status = END_SWIDTH;
		 }
	 }	 
else if(ptest.status == CHK_COUNT)
	 {
	  if(!lcd_buzy)
	    {
	     show_page(indx = 57);	 			// display checking sensor test
	     c_valve(3);
	     while(IBIT(PIODB,1))				// while not bottom limit
	     ndown(1);
    	  while(IBIT(PIODB,0))				// while not top limit	     
	     nup(1);
	     ndown(1);
	     ndown(check_count = 30);			// move down the minimum steps first
	  	 }
	  lcd_buzy = YES;
	  lk_printf("\x1bp310%3d",check_count); // (12/09/05)
	  
	  chk_volts(1);								// read #2 transducer
  	  if(pres[1] > 50)
		 {
		  o_valve(1);								// relieve pressure
		  wait100(6);
		  ndown(1);									// move down 1 step
		  check_count = check_count + 1;		// add 1 to check_count
		  c_valve(1);								// let pressure build
		  wait100(10);
		 }
   else
       {
        if(check_count > 44 || check_count < 36)//changed(44-36) (49-41)3/9/98 (52-44)11/30/04because adj seems low
        	{
          if(check_count > 44)ptest.result = CHK_COUNT_HI;//changed 40-50 12/09/05 final tst limits 34-50
          if(check_count < 36)ptest.result = CHK_COUNT_LO;//changed 36-44 12/17/05
        	}
        else
         {
			 mpump(flow_set = 0);
          ptest.result = CHK_COUNT_PASS;
         }
	  	  lcd_buzy = NO;  
	  	  ptest.start_time = ticker;	 	// sart timer for message display    
	  	  ptest.status = END_CHK_COUNT;
		 }
        
	 }
return;
}
/*****************************************************************************/
/**********************************task2()************************************/
/************************* WAITS TO START TESTS ******************************/
indirect task2()
{
if(!sys_up || setup)return;

   if(ptest.status == TOP_ADJUST) 					
     {
     	// adjusting top sensor
		if(IBIT(PIODB,0))lk_printf("\x1bp314*ON* ");
		if(!IBIT(PIODB,0))lk_printf("\x1bp314-OFF-");
		chk_keybd();           
     }    
else if(ptest.status == HOMEING) 					// wait until injector is home
     {
      if(injector == home)ptest.status = NEEDLEWASH;      
     }    
else if(ptest.status == NEEDLEWASHING) 			// wait until injector is down
     {
      if(injector == down)
        {
         show_page(indx = 18);						// make sure graduate is in place
         ptest.status = IDLE;
        }       
     }    
else if(ptest.status == PRIMING)
     {
     if(ticker - ptest.start_time >= 10)			// Purge needle wash for 10 seconds
       {
       vpump(NO);
       c_valve(4);	
       show_page(indx = 19);							// Empty graduate, press enter
       ptest.status = IDLE;
       }
     }
else if(ptest.status == WASHING)
     {
     if(ticker - ptest.start_time >= 15)			// Run Wash pump for 15 seconds
       {
       vpump(NO);
       c_valve(4);
       show_page(indx = 20);							// minimum 1.25 mls
       ptest.status = IDLE;
       }
     }
else if(ptest.status == NPURGING)
     {
     if(ticker - ptest.start_time >= 13)			// Purge needle for 13 seconds
       {
       o_valve(2);										// open first to start purging restrictor
       needle_home();
       o_valve(1);
       ptest.status = PURGE;
       }
     }
else if(ptest.status == PURGING)
     {
     if(ticker - ptest.start_time >= 15)			// Purge system & uut for 15 seconds
       {
       mpump(flow_set = 200);							// slow pump down 
       ptest.status = PRESSURIZING;
       }
     }
else if(ptest.status == WAITING)
     {
     if(ticker - ptest.start_time <= 300)
       {
        chk_volts(0);
        if((pres[0] >= pressr/2) && (pres[0] <= pressr - 1000))mpump(flow_set = 245);  // 1/2 way to pressure so,slow down.
		  if(pres[0] >= pressr - 300)mpump(flow_set = 255);
        if(pres[0] >= pressr)						   // have we reached set pressure for decay test?
        	 {
        	  mpump(flow_set = 0);
        	  ptest.start_time = ticker;
        	  chk_volts(0);
           ptest.start_press = pres[0];
           ptest.status = RUNNING;
          }
        }
       else
        {
			mpump(flow_set = 0);
			o_valve(1);
			ptest.result = RAMP_FAIL;			// error! couldn't reach pressure
		   ptest.status = OTHER;    
        }        
      }
else if(ptest.status == AZWAITING)
     {
     if(ticker - ptest.start_time <= 300)
       {
        chk_volts(0);
        if((pres[0] >= pressr/2) && (pres[0] <= pressr - 1000))mpump(flow_set = 245);  // 1/2 way to pressure so,slow down.
		  if(pres[0] >= pressr - 300)mpump(flow_set = 255);
        if(pres[0] >= pressr)						   // have we reached set pressure for decay test?
        	 {
        	  mpump(flow_set = 0);
        	  ptest.start_time = ticker;
        	  chk_volts(0);
           ptest.start_press = pres[0];
           ptest.status = AZRUNNING;
          }
        }
        else
        {
			mpump(flow_set = 0);
			o_valve(1);
			ptest.result = AZRAMP_FAIL;			// error! couldn't reach pressure
		   ptest.status = OTHER;    
        }
      }
      
else if(ptest.status == RPURGING)
     {
     if(ticker - ptest.start_time >= 10)		// Purge system & uut for 10 seconds
       {
        mpump(flow_set = 0);						// stop pump
        ptest.status = BACKPRESSURE;
       }
     }
else if(ptest.status == BPRESSURIZING)
     {
      chk_volts(0);
      if(pres[0] <= 500)
        {
         mpump(flow_set = flow_set - 2);    		 // increase flow until 500 psi back pressure
         if(flow_set <= 2)
           {
            mpump(flow_set = 0);
		      ptest.result = BPRESS_FAIL;			// error! couldn't reach pressure
		      ptest.status = OTHER;    
           }   
        }
      else
        {
        	chk_volts(1);
        	step_count = 0; 				//	reset motor step count
         down_count = 0;				// reset down_count
         seal_count = 0;				// reset seal count
         ptest.status = B_TOP_SEAL; 
        }
     }       
else if(ptest.status == AUTO_ZERO)
     {
     if(ticker - ptest.start_time >= 15)		// Purge system & uut for 15 seconds
       {
       mpump(flow_set = 200);						// slow pump down
       ptest.status = AZPRESSURIZING;
       }
     }
return;
}
/****************************************************************************/
/**********************************task3()***********************************/
/******************FORMATS AND DISPLAYS TEST RESULTS ************************/
indirect task3()
{
int l;

if(!sys_up || setup)return;
l = l == 1 ? 0 : 1;
if(ptest.status == STOPPED || ptest.status == END_DECAY || ptest.status == END_CHK_COUNT ||
ptest.status == END_DCOUNT || ptest.status == END_SWIDTH || ptest.status == AZEND_DECAY || ptest.status == OTHER)
 {
  if(l && !setup && !functflg && ptest.result != DKPASS && ptest.result != DCPASS &&
  ptest.result != SWPASS && ptest.result != AZDKPASS && ptest.result != CHK_COUNT_PASS)
	 {
	  if(ptest.result == DKFAIL || ptest.result == DCMINFAIL || ptest.result == CHK_COUNT_LO ||
	     ptest.result == CHK_COUNT_HI || ptest.result == DCMAXFAIL || ptest.result == SWFAIL)
		 {	
	     show_page(44);	// retest
	     wait(5);
	    }
     else show_page(1);									// ready to test
     wait(2);
    }
  if(ptest.abort == NO && !l && !functflg)
    {
     if(ptest.status == END_DECAY)
		 {     
        if(ptest.result == DKPASS)
          {
           if(!lcd_buzy)
           	 {
           	  show_page(indx = 30);	         	// decay passed
           	  lk_printf("\x1bp115%4d",dkspec);
              lk_printf("\x1bp309%4d",(int)ptest.decay_press);
              lcd_buzy = YES;
             }
           if(ticker - ptest.start_time >= 10)
             {
              lcd_buzy = NO;
				  ptest.result = WAITING;
              ptest.status = RPURGE;				// Start purge for down and seal counts
             } 
          }
        if(ptest.result == DKFAIL)
          {
           show_page(indx = 31);						// decay failed
           lk_printf("\x1bp115%4d",dkspec);
           lk_printf("\x1bp309%4d",(int)ptest.decay_press);
           outport(PIODA,0x00);						// turn windings off
           wait(5);
           //ptest.status = STOPPED;
          }
       }
else if(ptest.status == AZEND_DECAY)
		 {
		  c_valve(1);
   	  c_valve(2);
   	  c_valve(3);    
        if(ptest.result == AZDKPASS)
          {
           if(!lcd_buzy)
           	 {
           	  show_page(indx = 30);	         	// auto zero decay passed
           	  lk_printf("\x1bp115%4d",azdkspec);
              lk_printf("\x1bp309%4d",(int)ptest.azdecay_press);
              lcd_buzy = YES;
             }
           if(ticker - ptest.start_time >= 10)
             {
              lcd_buzy = NO;
				  ptest.result = WAITING;
              ptest.status = STOPPED;					// auto zero done & ready to test
              azero = NO;
             } 
          }
        if(ptest.result == AZDKFAIL)
          {
           show_page(indx = 31);							// decay failed
           lk_printf("\x1bp115%4d",azdkspec);
           lk_printf("\x1bp309%4d",(int)ptest.azdecay_press);
           outport(PIODA,0x00);							// turn windings off
           wait(5);
           //ptest.status = STOPPED;
          }
       }       
else if(ptest.status == END_DCOUNT)
		 {     
        if(ptest.result == DCPASS)
          {
           if(!lcd_buzy)
             {
              show_page(indx = 32);						// down count passed
           	  lk_printf("\x1bp316%3d",down_count);
           	  lcd_buzy = YES;
           	 }
           if(ticker - ptest.start_time >= 10)
             {
              lcd_buzy = NO;
              outport(PIODA,0x00);						// turn windings off
				  ptest.result = WAITING;
              ptest.status = SWIDTHING; 				// Start seal width test
             }
          }
        if(ptest.result == DCMINFAIL)
          {
           show_page(indx = 33);							// Minimum down count failed
           lk_printf("\x1bp117%3d",dncount_min);
           lk_printf("\x1bp316%3d",down_count);
           outport(PIODA,0x00);							// turn windings off
           wait(5);
           c_valve(1);
   		  c_valve(2);
   		  c_valve(3);
           //ptest.status = STOPPED;
          }
        if(ptest.result == DCMAXFAIL)
          {
           show_page(indx = 40);							// Maximum down count failed
           lk_printf("\x1bp117%3d",dncount_max);
           lk_printf("\x1bp316%3d",down_count);
           outport(PIODA,0x00);							// turn windings off
           wait(5);
           c_valve(1);
   		  c_valve(2);
   		  c_valve(3);
           //ptest.status = STOPPED;
          }
       }
else if(ptest.status == END_CHK_COUNT)
		 {     
        if(ptest.result == CHK_COUNT_PASS)
          {
           if(!lcd_buzy)
             {
              show_page(indx = 60);						// down count passed
              lk_printf("\x1bp316%3d",check_count);
           	  lcd_buzy = YES;
           	 }
           if(ticker - ptest.start_time >= 10)
             {
              lcd_buzy = NO;
              needle_home();
              outport(PIODA,0x00);						// turn windings off
				  c_valve(1);
				  c_valve(2);
				  c_valve(3);
              ptest.result = COMPLETE; 					// all tests done
             }
          }
        if(ptest.result == CHK_COUNT_LO)
          {
           show_page(indx = 58);							// Minimum down count failed
           lk_printf("\x1bp316%3d",check_count);
           outport(PIODA,0x00);							// turn windings off
           wait(5);
          }
        if(ptest.result == CHK_COUNT_HI)
          {
           show_page(indx = 59);							// Maximum down count failed
           lk_printf("\x1bp316%3d",check_count);
           outport(PIODA,0x00);							// turn windings off
           wait(5);
          }
        if(ptest.result == COMPLETE)
        	 {
        	  show_page(indx = 60);
        	  lk_printf("\x1bp316%3d",check_count);
        	  wait(5);
        	 }
       }
else if(ptest.status == END_SWIDTH)
		 {     
        if(ptest.result == SWPASS)
          {
           if(!lcd_buzy)
             {
              show_page(indx = 34);					   // seal width passed
           	  lk_printf("\x1bp314%3d",seal_count);
           	  lcd_buzy = YES;
           	 }
           if(ticker - ptest.start_time >= 10)
             {
              lcd_buzy = NO;
              outport(PIODA,0x00);				   					// turn windings off
              if(!IBIT(PIODB,6))ptest.status = TOP_SENSOR;	   // testing injectors
              if(!IBIT(PIODB,5) && IBIT(PIODB,6))					// Testing 717 Seal Packs
   				 {
   				  needle_home();			
   				  c_valve(1);
   				  c_valve(2);
   				  c_valve(3);
   				  ptest.result = COMPLETE;								// all tests passed
   				 }          	
	           }
          }
        if(ptest.result == SWFAIL)
          {
           show_page(indx = 35);						// seal width failed
           lk_printf("\x1bp314%3d",seal_count);
           outport(PIODA,0x00);				   	// turn windings off
           wait(5);
           c_valve(1);
   		  c_valve(2);
   		  c_valve(3);
          }
        if(ptest.result == COMPLETE)
        	 {
        	  show_page(indx = 60);
        	  wait(5);
        	 }  
       }

else if(ptest.status == OTHER)
	    {
	     if(ptest.result == B_TOP_SEAL_FAIL)show_page(indx = 47);
	     if(ptest.result == B_TOP_SEAL_FAIL2)show_page(indx = 54);
	     if(ptest.result == BPRESS_FAIL)show_page(indx = 41);
	     if(ptest.result == TSENSOR_FAIL)show_page(indx = 42);
	     if(ptest.result == BSENSOR_FAIL)show_page(indx = 43);
	     if(ptest.result == RAMP_FAIL)show_page(indx = 55);
	     if(ptest.result == AZRAMP_FAIL)show_page(indx = 55);
	     if(ptest.result == COMPLETE)show_page(indx = 60);
	 	  wait(5);
		  c_valve(1);
        c_valve(2);
        c_valve(3);
	    }   
       
    }   
  if(ptest.abort == YES && !l && !functflg)
	 {
     show_page(3);
     wait(5);
    }
 }
return;
}
/****************************************************************************/
/**********************************task4()***********************************/
/****************************************************************************/
indirect task4()
{
static int l;
if(!sys_up)return;
ticker++;
l = l == 1 ? 2 : 1;
lk_led(l);
return;
}
/****************************************************************************/
/**********************************task5()***********************************/
/*******************MEASURES TRANSDUCERS IN DIAG MODE************************/
indirect task5()
{
if(!sys_up)return;
  if(indx >= 9 && indx <= 10)
    {     
     if((indx - 9) == 0)		// transducer # 1
       {
       mpump(flow_set = 0);
       c_valve(3);
       o_valve(2);
       o_valve(1);
       }
     if((indx - 9) == 1)		// transducer # 2
       {
       mpump(flow_set = 0);
       c_valve(3);
       o_valve(2);
       c_valve(1);
       }
     chk_volts(indx - 9);
     lk_printf("\x1bp311%4d",(int)pres[indx - 9]);
    }
    
  if(indx == 11)					// air switch
  	 {
	 if(!IBIT(PIODB,2))lk_printf("\x1bp311<");
	 if(IBIT(PIODB,2))lk_printf("\x1bp311>");
	 o_valve(3);
    o_valve(2);
    o_valve(1);
    if(IBIT(PIODB,2))mpump(flow_set = 36);		 	 
  	 }
    
chk_clock(page[6].line[3],page[7].line[3]);
return;
}
/****************************************************************************/
/**********************************backgnd()*********************************/
/*********************SCANS KEY BOARD, HITS WATCH DOG************************/
indirect backgnd()
{
static int err;
while(1)
     {
      chk_keybd();
      hitwd();
      chkcal();    /* check when calibration is due */
      err = wderror();
          if(err != 0)
            {
             run_cancel(TASK0);   /* run the diag task only*/
             run_cancel(TASK1);
             run_cancel(TASK2); 
             run_cancel(TASK3);
             run_cancel(TASK4); 
             run_cancel(TASK6); 
             run_every(TASK5,10);
             sprintf(page[0].line[0], "**SOFTWARE FAILURE**"); 
             sprintf(page[0].line[1], "TIME OUT ON WATCHDOG"); 
             sprintf(page[0].line[2], "PLEASE CALL T.E. FOR");
             sprintf(page[0].line[3], " ASSISTANCE AT X3054");
             show_page(0);
             hv_wr(0x00); 
             while(1)
                  {
                   ;
                  }
            }
     }
return;
}
/****************************************************************************/
/********************************chk_volts()************************************/
/************************* CHECKS THE AD VOLTAGE ****************************/
chk_volts(chnl)
int chnl;
{
double sum;
int count;
int x;
sum =  0;

       for(x = 0; x < 25; x++)
           {
            sum += ad_rd10(chnl + 8);
           }
           count = sum/25;
           pres[chnl] = (count * 2.442);
           sum = 0;

return;
}
/****************************************************************************/
/*******************************chk_keybd()**********************************/
/**************************CHECKS KEYBOARD FOR INPUT*************************/
chk_keybd()
{
    curkey = lk_kxget(0) ; /* get a key from queue */
    if(isdigit(curkey))
      {
       if(page[indx].page_type == INPUT)
         {
          lk_setbeep(100);
          stuffit();
          return;
         }
      }
 if(isalpha(curkey))
   {       
    lk_setbeep(100);
    switch(curkey)
          {
           case 'A':
              if(error)break;
              if(!caldue && !functflg && sys_up && !setup)
                 {
                  functflg = YES;
                  test_abort();
                 }
               break;

           case 'T':
              if(error)break;
              if(ptest.status != STOPPED)
              	 {
              	  if(ptest.result == DKPASS || ptest.result == AZDKPASS || ptest.result == DCPASS || ptest.result == SWPASS)
              	    {
              	     break;
              	    }
              	  }  
              if(!caldue && !functflg && sys_up && !setup)
                 {
                  functflg = YES;
                  if(!azero)show_page(indx = 2);
                  else show_page(indx = 45);
                  break;
                 }                          
              if(access_ok || (setup && setup_status.ready))up_arrow();
              break;

           case 'D':
               if((!functflg && sys_up && !setup) || setup_status.ready == NO)
                 {
                  diagflg = YES;
                  functflg = YES;
                  run_cancel(TASK0);   /* run the diag task only*/
                  run_cancel(TASK1);
                  run_cancel(TASK2); 
                  run_cancel(TASK3);
                  run_cancel(TASK4); 
                  run_cancel(TASK6); 
                  run_every(TASK5,10);
                  show_page(indx = 4);
                  break;
                 }
                 if(access_ok || setup || setup_status.ready == YES)down_arrow();
                 break;

           case 'E':
					if(indx !=2 && indx != 18 && indx != 19 && indx != 20 && indx != 58 && indx != 31 &&
					 indx != 33 && indx != 35 && indx != 40 && indx != 41 && indx != 45 && indx != 46 && indx != 59)
					{
               if(!is_it_in)break;  /* is the buffer full of what it needs? */
					}
               enter();
               loc = 0;
               break;

           case 'F':
               if(access_ok)break;
               //setup_status.dcountmin = NO;
               //setup_status.dcountmax = NO;
               //setup_status.swidth = NO;
               //setup_status.decay = NO;
               //setup_status.pressr = NO;
               //setup_status.ready = YES;
               //setup = YES;
               //show_page(5);
               //indx = 14;
               break;

           case 'C':
               if(error)break;
               if(setup)
                 {
                  if(setup_status.dcountmax && setup_status.dcountmin && setup_status.decay && setup_status.pressr)
						  {
                     setup = NO;
                    }
                  if((dkspec >= pressr) || dkspec == 0)setup = YES;
                 }
               if(sys_up)get_out();
               break;
          
          }
   }

return;
}
/****************************************************************************/
/**********************************stuffit()*********************************/
/******************STUFFS KEYPAD ENTRIES INTO THE BUFFER*********************/
stuffit()
{
 int x;
 if(loc == 0)
  {
  for(x = 0;x < page[indx].max_width;x++)
       {
       lk_printf("%s",page[indx].cursor_pos[x]);
       lk_putc('\x20');
       }
   lk_printf("%s",page[indx].cursor_pos[0]);
   }
 keybuf[loc] = curkey;
 lk_printf("%c",curkey);
 if(page[indx].min_width <= (++loc) && loc <= page[indx].max_width)is_it_in = 1;
 if(loc == page[indx].max_width)loc = 0; 
 lk_printf("%s",page[indx].cursor_pos[loc]);
return;
}        
/****************************************************************************/
/**********************************enter()***********************************/
/****************************ENTER THE SELECTION*****************************/
enter()
{
switch(indx)
      {
       case 2: 
            start_test();
            break;

       case 4:
            check_access();
            break;

       case 5:
            break;

       case 6:
            set_the_time(page[6].line[3]);
            break;

       case 7:
            set_the_date(page[7].line[3]);
            break;

       case 8:
            set_cal_date(page[8].line[3]);
            break;

       case 12:
            set_dncountmin(page[12].line[3]);
            break;

       case 13:
            set_dncountmax(page[13].line[3]);
            break;

       case 14:
            set_dkspec(page[14].line[3]);
            break;

       case 15:
            set_pressure(page[15].line[3]);
            break;

       case 18:
            ptest.status = PRIME;
            break;

       case 19:
            ptest.status = WASH;
            break;

       case 20:
            ptest.status = NPURGE;
            break;

       case 31:								// failed decay retest
				lcd_buzy = NO;
       		needle_wash();
       		o_valve(3);
            mpump(flow_set = 30);
       		o_valve(2);						// open first to start purging restrictor
       		needle_home();
       		o_valve(1);
       		ptest.status = PURGE;
       		ptest.result = WAITING;
            break;
		
    	 case 33:								// failed minimum down count
				lcd_buzy = NO;
    	 		needle_home();
 				ptest.status = RPURGE;
 				ptest.result = WAITING;
				break;

    	 case 40:								// failed maximum down count
				lcd_buzy = NO;
    	 		needle_home();
				ptest.status = RPURGE;
				ptest.result = WAITING;
				break;

    	 case 35:								// failed seal count
				lcd_buzy = NO;
    	 		needle_home();
				ptest.status = RPURGE;
				ptest.result = WAITING;
				break;
				
    	 case 41:								// failed to reach back pressure					
    	 		down_count = 0;				// reset down_count
         	seal_count = 0;				// reset seal count
         	step_count = 0;				// reset step_count     
				ptest.status = RPURGE;
				ptest.result = WAITING;	
				break;
								
       case 45: 
            start_test();
            break;
            
    	 case 46:												// top sensor adjusted
    	 		lcd_buzy = NO;
    	 		if(!IBIT(PIODB,6) && IBIT(PIODB,5))		// Testing 2690 Injectors
				  {
				   check_count = 0;							// reset check sensor count
				   ptest.status = CHK_COUNT;	 			// Check sensor adjust
				   ptest.result = WAITING;
				  }
				 else
				  {
	    	 		outport(PIODA,0x00);		// turn windings off
    	 	   	ptest.result = COMPLETE;
				   ptest.status = OTHER;
				  }
				break;

       case 51:								// failed auto zero decay retest
       		ptest.status = SYS_COMPLIANCE;
            break;

    	 case 58:								// failed minimum down count
				lcd_buzy = NO;
				check_count = 0;				// reset check sensor count
				ptest.status = CHK_COUNT;	// Check sensor adjust
 				ptest.result = WAITING;
				break;

    	 case 59:								// failed maximum down count
				lcd_buzy = NO;
				check_count = 0;				// reset check sensor count
				ptest.status = CHK_COUNT;	// Check sensor adjust
 				ptest.result = WAITING;
				break;
				            				
      }

 exit:

is_it_in = 0;
cleanbufr(keybuf,sizeof(keybuf));
return;
}
/****************************************************************************/
/*******************************up_arrow()***********************************/
/******************DISPLAYS DIAG PAGES IN ASCENDING ORDER********************/
up_arrow()
{
if(setup && !access_ok)
 {
  if(indx + 1 > SET_TOP)
    {
     indx = SET_BOTTOM;
     show_page(SET_BOTTOM);
     return;
    }
 }
else
 {
  if(indx + 1 > TOP_PAGE)
    {
     indx = BOTTOM_PAGE;
     show_page(BOTTOM_PAGE);
     return;
    }
 }
show_page(++indx);
return;
}
/****************************************************************************/
/*******************************down_arrow()***********************************/
/******************DISPLAYS DIAG PAGES IN DESCENDING ORDER*******************/
down_arrow()
{
if(setup && !access_ok)
 {
  if(indx - 1 < SET_BOTTOM)
    {
     indx = SET_TOP;
     show_page(SET_TOP);
     return;
    }
 }
else
 {
  if(indx - 1 < BOTTOM_PAGE)
    {
     indx = TOP_PAGE;
     show_page(TOP_PAGE);
     return;
    }
 }
  show_page(--indx);
return;
}
/****************************************************************************/
/*********************************get_out()**********************************/
/********************************EXITS SET-UP********************************/
get_out()
{
static int n;
 if(access_ok || indx == 4)
   {
    access_ok = NO;
    hv_wr(0x00);
    run_every(TASK0,10);   /* run task 0 every 10 ticks */
    run_every(TASK1,20);   /* run task 1 every 20 ticks */
    run_every(TASK2,30);   /* run task 2 every 30 ticks */
    run_every(TASK3,40);   /* run task 3 every 40 ticks */
    run_every(TASK4,50);   /* run task 4 every 50 ticks */
    run_every(TASK6,200);   /* run task 6 every 60 ticks */
    run_cancel(TASK5);     /* cancel task 5 until diagnostics are entered  */
    caldue = NO;
    chkcal();
   }

 setup_status.ready = NO;
 if(indx == 11)mpump(flow_set = 0);
 if(!caldue && !setup)indx = 1;	// test message 
 if(!caldue && setup)indx = 17; 	// setup message
 if(caldue)indx = 0;					// cal due message
 
 show_page(indx);
 is_it_in = 0;
 loc = 0;
 functflg = 0;
 diagflg = 0;
 cleanbufr(keybuf,sizeof(keybuf));
 if(!caldue && !setup)request(TASK6);
return;
}
/****************************************************************************/

/*******************************start_test()*********************************/
/**************************SETS STATUS TO START TEST*************************/
start_test()
{ 
 functflg = 0;
 ptest.abort = NO;
 lcd_buzy = NO;
 if(azero)ptest.status = SYS_COMPLIANCE;
 else ptest.status = HOME;
return;
}
/****************************************************************************/
/******************************test_abort()**********************************/
/************************CHANGES STATUS TO STOPPED***************************/
test_abort()
{
 lcd_buzy = NO;
 mpump(flow_set = 0);      			/* STOP PUMP */
 outport(PIODA,0x00);					// turn windings off
 functflg = 0;
 vpump(NO);
 vent_press();
 c_valve(1);
 c_valve(2);
 c_valve(3);
 ptest.result = WAITING;
 ptest.abort = YES;
 ptest.status = STOPPED; 
return;
}
/****************************************************************************/
/***************************check_access()***********************************/
/*************************CHECKS FOR PASSWORD********************************/
check_access()
{
 if(atoi(keybuf) == 1878)
   {
    setup_status.ready = YES;
    access_ok = YES;
    show_page(indx = 5);
   }
 else
   {
    functflg = 0;
    if(!setup)show_page(indx = 1);
    if(setup)show_page(indx = 17);	// setup message
   }
return;
}
/****************************************************************************/
/*****************************set_dncountmin()*******************************/
/*************************SETS DOWN COUNT FOR TEST***************************/
set_dncountmin(dcountmin)
char *dcountmin;
{
 dncount_min = atoi(keybuf);
 setup_status.dcountmin = YES;
 sprintf(dcountmin,"MIN DOWN COUNT= %d",dncount_min);
return;
}
/****************************************************************************/
/*****************************set_dncountmax()*******************************/
/*************************SETS DOWN COUNT FOR TEST***************************/
set_dncountmax(dcountmax)
char *dcountmax;
{
 dncount_max = atoi(keybuf);
 setup_status.dcountmax = YES;
 sprintf(dcountmax,"MAX DOWN COUNT= %d",dncount_max);
return;
}
/****************************************************************************/
/*****************************set_dkspec()***********************************/
/*************************SETS DECAY SPEC FOR TEST***************************/
set_dkspec(dspec)
char *dspec;
{
dkspec = atoi(keybuf);
setup_status.decay = YES;
sprintf(dspec," DECAY SPEC = %d  ",dkspec);
return;
}
/****************************************************************************/
/*****************************set_pressure()*********************************/
/****************************SETS TEST PRESSURE******************************/
set_pressure(dpress)
char *dpress;
{
pressr = atoi(keybuf);
if(pressr > 5000)return;
setup_status.pressr = YES;
sprintf(dpress,"  PRESSURE = %d   ",pressr);
return;
}
/****************************************************************************/
/*****************************set_the_time()*********************************/
/**************************SET THE CLOCKS TIME*******************************/
anymem set_the_time()
{
int HH, MM, SS;
char temp[3];

strncpy(temp,keybuf,2);
temp[2]=0;
HH = atoi(temp);

strncpy(temp,keybuf+2,2);
MM = atoi(temp);

strncpy(temp,keybuf+4,2);
SS = atoi(temp);

if(HH<=24 && MM<=59 && SS<=59)
  {
   dt[0].tm_hour = HH;
   dt[0].tm_min = MM;
   dt[0].tm_sec = SS;
   tm_wr(&dt[0]);  // set the time in the RTC
   ticker = clock();
  }
   
return;

}

/****************************************************************************/
/******************************set_the_date()********************************/
/****************************SET THE CLOCKS DATE*****************************/
anymem set_the_date()
{
int MM, DD, YYYY;
char temp[5];

strncpy(temp,keybuf,2);
temp[2]=0;
MM = atoi(temp);

strncpy(temp,keybuf+2,2);
temp[2]=0;
DD = atoi(temp);

strncpy(temp,keybuf+4,4);
temp[4]=0;
YYYY = atoi(temp);

if(MM>=1 && MM<=12 && DD>=1 && DD<=31 && YYYY>=1900 && YYYY<=2050)
  {
   dt[0].tm_mon = MM;
   dt[0].tm_mday = DD;
   dt[0].tm_year = YYYY - 1900;
   tm_wr(&dt[0]);  // set the date in the RTC
   ticker = clock();
  }
  
return;

}

/****************************************************************************/
/*****************************loadcaldate()**********************************/
/*************************LOADS CALIBRATION DUE DATE*************************/
anymem loadcaldate(char *caldue)
{
int n;

for(n=0; n<3; n++)caldate[n] = ee_rd(0x0a+n);  // read the eeprom

sprintf(caldue,"     %02d/%02d/%d",caldate[0],caldate[1],caldate[2]+1900);

dt[1].tm_mon = caldate[0];
dt[1].tm_mday = caldate[1];
dt[1].tm_year = caldate[2];
dt[1].tm_hour = 0;           // not used but set em to zero for accuracy
dt[1].tm_min = 0;
dt[1].tm_sec = 0;

calwhen = mktime(&dt[1]);

return;

}
/****************************************************************************/
/****************************set_cal_date()**********************************/
/*************************SETS WHEN CALIBRATION IS DUE***********************/
anymem set_cal_date(char *cal_due)
{
int n, MM, DD, YYYY;
char temp[5];

strncpy(temp,keybuf,2);
temp[2]=0;
MM = atoi(temp);

strncpy(temp,keybuf+2,2);
temp[2]=0;
DD = atoi(temp);

strncpy(temp,keybuf+4,4);
temp[4]=0;
YYYY = atoi(temp);

if(MM>=1 && MM<=12 && DD>=1 && DD<=31 && YYYY>=1900 && YYYY<=2050)
  {
   caldate[0] = MM;
   caldate[1] = DD;
   caldate[2] = YYYY - 1900;
   dt[1].tm_mon = caldate[0];
   dt[1].tm_mday = caldate[1];
   dt[1].tm_year = caldate[2];
   dt[1].tm_hour = 0;           // not used but set em to zero for accuracy
   dt[1].tm_min = 0;
   dt[1].tm_sec = 0;

   for(n=0; n<3; n++)ee_wr(0x0a+n,caldate[n]);

   calwhen = mktime(&dt[1]); 
   caldue = NO;
  }

sprintf(cal_due,"     %02d/%02d/%d     ",caldate[0],caldate[1],caldate[2]+1900);
    
return;

}
/****************************************************************************/
/***********************************()*********************************/
/*************************CHECKS IF CALIBRATION IS DUE***********************/
anymem chkcal()
{

       if((ticker > calwhen) && !access_ok && !caldue)
        {
         run_cancel(TASK0);   /* run the diag task only*/
         run_cancel(TASK1);
         run_cancel(TASK2); 
         run_cancel(TASK3);
         run_cancel(TASK4); 
         run_cancel(TASK6); 
         run_every(TASK5,15);
         sprintf(page[0].line[0]," CALIBRATION IS NOW ");
         sprintf(page[0].line[1],"  DUE ON THIS TEST  ");
         sprintf(page[0].line[2],"EQUIPMENT! CALL T.E.");
         sprintf(page[0].line[3],"AT X3054 FOR SERVICE");
         show_page(0);
         hv_wr(0x00); 			// close all valves & vacuum pump off
         caldue = YES;
        }

 return;
}
/****************************************************************************/
/********************************chk_clock()*********************************/
/************************CHECKS THE REAL TIME CLOCK**************************/
anymem chk_clock(char *time,char *date)
{

tm_rd(&dt[0]);

if(old_day != dt[0].tm_mday) // has the date changed?
  {
   old_day = dt[0].tm_mday;
   sprintf(date,"     %02d/%02d/%d     ",dt[0].tm_mon,dt[0].tm_mday,dt[0].tm_year+1900);
  }

if(old_sec != dt[0].tm_sec) // has the time changed?
  {
   old_sec = dt[0].tm_sec;
   sprintf(time,"      %02d:%02d:%02d      ",dt[0].tm_hour,dt[0].tm_min,dt[0].tm_sec); 
  }

return;

}
/****************************************************************************/
/**********************************wait()************************************/
/************PROGRAMABLE DELAY,(ABOUT 1 SEC PER UNIT OF ARG TIME*************/
anymem wait(seconds)
int seconds;
{
static int x;
seconds = seconds * 10;
   for(x=0; x<seconds; x++)
      {
       Ddelay_100ms();
       hitwd();
       chk_keybd();
       
      }
return;
}
/****************************************************************************/
/**********************************wait100()*********************************/
/************PROGRAMABLE DELAY,(ABOUT 100 MS PER UNIT OF ARG TIME************/
anymem wait100(msec)
int msec;
{
static int x;
   for(x=0; x<msec; x++)
      {
       Ddelay_100ms();
       hitwd();
       chk_keybd();
       
      }
return;
}
/****************************************************************************/
/********************************show_page()*********************************/
/************************WRITES PAGES TO THE LCD DISPLAY*********************/
anymem show_page(number)
int number;
{
      lk_printf("\x1be");
      lk_printf("\x1bp000%s",page[number].line[0]);   
      lk_printf("\x1bp100%s",page[number].line[1]);   
      lk_printf("\x1bp200%s",page[number].line[2]);   
      lk_printf("\x1bp300%s",page[number].line[3]);   
      if(page[number].page_type == INPUT)
        {
         lk_printf("%s",page[number].cursor_pos[0]);
        }  
      lk_printf("%s",page[number].cursor_type);
return;
}
/****************************************************************************/
/*********************************cleanbufr()********************************/
/*************************FILLS ARG BUFR WITH 0'S****************************/
anymem cleanbufr(bufr,size)
char *bufr;
int size;
{
static int x;
for(x = 0; x < size; x++)bufr[x] = 0;
return;
}
/****************************************************************************/
/*********************************vent_press()*******************************/
/************************* RELIEVE PRESSURE FROM UUT*************************/
vent_press()
{
c_valve(4);				// close needle wash valve
run_cancel(TASK6); 
o_valve(1);
o_valve(2);				// open valves 1 - 3 to relieve pressure
o_valve(3);
wait(1);
run_every(TASK6,200);
return;
}
/****************************************************************************/
/********************************c_valve()***********************************/
/*****************************CLOSE VALVES***********************************/
c_valve(valve)
int valve;
{
res(&hout,(8 - valve));    // valves 1-4 are wired in descending order from
hv_wr(hout);               // bit 7 of hi-volt port
return;
}
/****************************************************************************/
/********************************o_valve()***********************************/
/******************************OPEN VALVES***********************************/
o_valve(valve)
int valve;
{
set(&hout,(8 - valve));		// valves 1-4 are wired in descending order from
hv_wr(hout);					// bit 7 of hi-volt port
return;
}
/****************************************************************************/
/********************************vpump()*************************************/
/******************************CONTROL WASH PUMP*****************************/
vpump(wash)
int wash;
{
 if(wash) hv_wr(hout |= 0x0f);	// turn on wash pump
 else
     {									// wash pump wired to bits 0-3
		hout |= 0x0f;
 		hv_wr(hout ^= 0x0f);	   	// turn off wash pump
	  }
return;
}
/****************************************************************************/
/**********************************task6()***********************************/
/*********** MONITOR INLET SENSOR, SYSTEM PRESSURE & AIR SOURCE *************/
indirect task6()
{
int x;

if(!sys_up || setup || diagflg)return;

	 if(IBIT(PIODB,3))
	 	{
	 	 mpump(flow_set = 0);
	 	 ptest.status = ERROR;
	 	 error = YES;
	    show_page(indx = 56);					// display air in inlet message
	    while(IBIT(PIODB,3))
	    		{
	    		 chk_keybd();                 
				 if(diagflg || setup)
               {
                error = NO;
                return;
               }
             hitwd();
				}
       error = NO;             
       ptest.status = STOPPED;             
       ptest.abort  = WAITING;
       show_page(indx = 1);	    
	   }

	 if(!IBIT(PIODB,2))
	 	{
	 	 mpump(flow_set = 0);
	 	 ptest.status = ERROR;
	 	 error = YES;
	    show_page(indx = 16);					// display low air message
	    while(!IBIT(PIODB,2))
	    		{
	    		 chk_keybd();                 
				 if(diagflg || setup)
               {
                error = NO;
                return;
               }
             hitwd();
				}
       error = NO;             
       ptest.status = STOPPED;             
       ptest.abort  = WAITING;
       show_page(indx = 1);	    
	   }

	   
chk_volts(0);
          if(pres[0] > 6000)
            {
             mpump(flow_set = 0);
             vent_press();
             ptest.status = ERROR;
             error = YES;
             show_page(indx = 27);			// displaly over pressure message
             while(pres[0] > 1000)
             		{
                   chk_keybd();                 
				       if(diagflg || setup)
             	      {
                		 error = NO;
                      return;
                	   }
                	 hitwd();
                	 chk_volts(0);
				 		}
             error = NO;             
             ptest.status = STOPPED;             
             ptest.abort  = WAITING;
             show_page(indx = 1);
            }
return;
}
/****************************************************************************/
/********************************mpump()******************************************

	Ramps M510 Pump to specified flow rate.
	Decrease flow rate by increasing flow_set.
	
*********************************************************************************/

mpump(frate)
int frate;
{
int x,y;
if((frate < flow) && (frate != 0))
	{
   for(x = flow;x > frate;x--)  /* increase flow rate */
	   {
	    outport ( CTC2, 3 );        /* reset CTC2 */
       setctc ( 2, 1,x, 1 );       /* initialize ctc, enable interrupts */
       if((x < 70) && (x > 35))
       if((x <= 35) && (x > 25))wait(1);
       if((x <= 25) && (x > 20))wait(3);
       else for(y = 0;y < 1200;y++);
	   }
	 }  

if((frate > flow) && (frate != 0))
	{
   for(x = flow;x < frate;++x)  /* decrease flow rate */
	   {
	    outport ( CTC2, 3 );        /* reset CTC2 */
       setctc ( 2, 1,x, 1 );       /* initialize ctc, enable interrupts */
       if((x < 70) && (x > 35))
       if((x <= 35) && (x > 25))wait(1);
       if((x <= 25) && (x > 20))wait(3);
       else for(y = 0;y < 1200;y++);
	   }
	 }  
if(frate == 0)						  /* Stop Pump */
	{
	 outport ( CTC2, 3 );           /* reset CTC2 */
	 x = 255;   
	}  
flow = x;	
return;
}
/*******************************************************************************/

#INT_VEC CTC2_VEC ccc         /* set interrupt vector for interrupt routine */

/* this interrupt routine toggles bit zero on digital port a */

interrupt reti int ccc ()
{
	if(IBIT(PIODB,7)) IRES(PIODB,7);
	else
	   ISET(PIODB,7);
}

/*******************************************************************************/
      
/************************** step() ******************************************/
int step(int dir)
{
 int a,x;

 if(dir == down)
   {
   	
		  stepstate++;
		  if(stepstate > 3) stepstate = 0;
        outport(PIODA,state[stepstate]);
        for(x=0;x<500;x++);		// 367 = 17 hz; 120 = 52 hz; 296 = 22 hz
       
   }

 if(dir == up)
   {
       
        stepstate--;
		  if(stepstate < 0) stepstate = 3;
        outport(PIODA,state[stepstate]);
        for(x=0;x<500;x++); 			// 367 = 17 hz; 120 = 52 hz; 296 = 22 hz          
       
   }
return;
}
/********************************************************************************/
/************************** hstep() ******************************************/
int hstep(int dir)
{
 int a,x;

 if(dir == down)
   {
   	
		  hstepstate++;
		  if(hstepstate > 7) hstepstate = 0;
        outport(PIODA,hstate[hstepstate]);
        for(x=0;x<250;x++);		// 367 = 17 hz; 120 = 52 hz; 296 = 22 hz
       
   }

 if(dir == up)
   {
       
        hstepstate--;
		  if(hstepstate < 0) hstepstate = 7;
        outport(PIODA,hstate[hstepstate]);
        for(x=0;x<250;x++); 			// 367 = 17 hz; 120 = 52 hz; 296 = 22 hz          
       
   }
return;
}
/********************************************************************************/
/********************************needle_home()************************************

	Read limit switch, run needle UP until top limit, then down 10 steps.
	if # of steps is greater than 1960 and top sensor wasn't detected, then
	set testabort and display error.
	
*********************************************************************************/
needle_home()
{
 int x;
 x = 0;
 injector = NO;
 show_page(25);											      	// injector homeing message
 if(ptest.status == HOME)ndown(200);
 if(ptest.status != END_DECAY && ptest.status != END_DCOUNT && ptest.status != END_CHK_COUNT
  && ptest.status != END_SWIDTH && ptest.status != CHK_COUNT)ptest.status = HOMEING;
 if(IBIT(PIODB,0))													// if not top limit
   {
	 chk_keybd();
    while(IBIT(PIODB,0) && x<2407)								// while not top limit
        {
         hstep(up);
         x++;
        }					       
    if(x>2400 || x<3)
     { 
      ptest.result = TSENSOR_FAIL;								// error! didn't see top limit
      ptest.status = OTHER;    
     }
   }   
 outport(PIODA,0x00);												// turn windings off
 injector = home;
return;
}
/********************************************************************************/
/********************************needle_wash()***********************************

	Read limit switch, run needle DOWN until bottom limit, then down 400 steps.
	if # of steps is greater than 1960 and bottom sensor wasn't detected, then
	set testabort and display error.
	
*********************************************************************************/
needle_wash()
{
 int x;
 x = 0;
 injector = NO;
 show_page(26);											      	// needle down message
 if(ptest.status != END_DECAY && ptest.status != CHK_COUNT && indx != 31)ptest.status = NEEDLEWASHING;
 if(IBIT(PIODB,1))													// if not bottom limit
   {
    chk_keybd();
    while(IBIT(PIODB,1) && x<1807)								// while not bottom limit
    		{
          hstep(down);
          x++;
         } 					       
   }  
 if(x>1800 || x<3)
   {
    ptest.result = BSENSOR_FAIL;								// error! didn't see bottom sensor
    ptest.status = OTHER;    
   }

 ndown(400);
 outport(PIODA,0x00);												// turn windings off
 injector = down;
return;
}
/********************************************************************************/
/********************************ndown()******************************************
	run needle down x number of steps.	
*********************************************************************************/
ndown(amount)
int amount;
{
 while(amount > 0)
		{
		 step(down);
		 amount--;
		 }
return;
}
/********************************************************************************/
/********************************************************************************/

/********************************nup()******************************************
	run needle up x number of steps.	
*********************************************************************************/
nup(amount)
int amount;
{
 while(amount > 0)
		{
		 step(up);
		 amount--;
		 }
return;
}
/********************************************************************************/
/****************************** Verify_Check_Sum() ******************************/
char Verify_Check_Sum()
{
unsigned int Check_Sum, sum;
long xmem_address;

// compute the check sum, add all locations except the last 2!
for(xmem_address = 0, sum = 0; xmem_address < ( ((long)PROM_SIZE * 1024) - 2); sum += xgetchar(xmem_address), xmem_address++);

// read the last two memory locations for the reference check sum
Check_Sum = ((xgetchar(xmem_address)) << 8) + xgetchar(++xmem_address);
  
// compare the sum with the reference check sum and return pass or fail
if(sum != Check_Sum)return(0);
else return(1);

}

/*************************************************************************************/      
