/*
	5keyscan.c

   PK21xx/Rugged Giant and PK22xx/Little Star Sample Program that combines
   5keycode.c and scanblk.c.
   
   The funcblks are run under the background routine of the real time kernel.
   
   Runs on Z-World's Demo Unit Two
*/

#use "default.h"
#use cplc.lib
#use 5key.lib
#use 5keyextd.lib
#use gate_p.lib
#use rtk.lib

#if !(BOARD_TYPE==CPLC_BOARD || BOARD_TYPE==L_STAR)
#fatal "This program only runs on a PK21xx/Rugged Giant or a PK22xx/Little Star"
#endif

/***Begin Globals real_time_kernel  */
int task0(void), task1(void), task2(void), task3(void), 
    task4(void), task5(void), backgnd(void);

int (*Ftask[])() =
{
    task0, task1, task2, task3, task4, task5, backgnd
};

#define NTASKS 7

#define TASK0 0
#define TASK1 1
#define TASK2 2
#define TASK3 3
#define TASK4 4
#define TASK5 5

/***End Globals real_time_kernel */


#define RUNKERNEL 1
char time0[15];
char *time0_help[] =
     {
         "Set system time,",
         "use field, up &",
         "down key to chng"
     };
char date0[15];
char *date0_help[] =
     {
         "Set system date,",
         "use field, up &",
         "down key to chng"
     };


root main()
{
    uplc_init();

#if BOARD_TYPE==CPLC_BOARD
        upoint[0].ulow_set  = 6950;
        upoint[0].uhigh_set = 7000;
        U1HIGH = up_uncal(upoint[0].uhigh_set);
        U1LOW  = up_uncal(upoint[0].ulow_set);
#endif

    backgnd();               // background task
}

indirect task0(void)
{                            // task not used
}


indirect task3(void)
{
                             // task not used
}

indirect task1(void)
{
                             // task not used
}

indirect task2(void)
{
}

// task server for the 5key system
indirect task4(void)
{
    while (1)
    {
        time_date_menu();
        input_output_menu();

#if BOARD_TYPE==CPLC_BOARD
        uset_menu();
#endif

    }
}

indirect task5(void)
{
                             // task not used
}

indirect backgnd(void)
{
    request(TASK4);
    demo_scan();             // scan block is always running

}                            // end of background

// item server for board input output
int input_output_menu(void)
{
    lcd_server(3, 0L, "Input Output Set");
    while (1)
    {
#if BOARD_TYPE==CPLC_BOARD
        if (_5key_uinput() == MENU) 
            return;
        if (_5key_diginput() == MENU) 
            return;
        if (_5key_12out() == MENU) 
            return;
        if (_5key_dacout() == MENU) 
            return;
#elif BOARD_TYPE==L_STAR
        if (_5key_bank1dig() == MENU) 
            return;
        if (_5key_bank2dig() == MENU) 
            return;
        if (_5key_14out() == MENU) 
            return;
#endif
    }
}

// item server for time date setup
int time_date_menu(void)
{
    lcd_server(3, 0L, "Time Date Set");
    while (1)
    {
        if (_5key_date("date   ", date0, date0_help, 
        sizeof(date0_help), 1, 1, 10) == MENU) 
            return;
        if (_5key_time("time   ", time0, time0_help, 
        sizeof(time0_help), 1, 1, 10) == MENU) 
            return;
    }
}


#define AND &&
#define OR  ||
#define NOT !

#define ON  1
#define OFF 0

#define START      DIGIN3    // DIGIN3 is a NC switch
#define NOT_STOP   DIGIN2    // DIGIN2 is a NO switch
#define MACHINE_ON DIGIN1    // DIGIN1 is a toggle switch
#define MOTOR      OUT1      // OUT1 drives a MOTOR
#define OIL_PUMP   OUT2      // OUT2 drives a PUMP
#define START_T1   T1I
#define T1_DONE    T1O
#define START_T2   T2I
#define T2_DONE    T2O

#define START_T3 T3I
#define START_T4 T4I
#define START_T5 T5I
#define T3_DONE  T3O
#define T4_DONE  T4O
#define T5_DONE  T5O

#define LITE1   OUT8
#define LITE2   OUT9
#define LITE3   OUT10

#define HEATER_ON_OFF  OUT3

#if BOARD_TYPE==CPLC_BOARD
#define THERMISTOR U1IN
#else
#define THERMISTOR DIGIN9    // use DIG9 to mimic thermistor input
#endif

extern FuncBlk motor_pump;
extern FuncBlk sequence_lite;
extern FuncBlk heater;

int demo_scan(void)
{
    while (1)                // do an infinite loop
    {
        runwatch();          // monitor with the watch window
        funcblk monitor_start_stop always_on
        {
            waitfor(START AND MACHINE_ON);
            CoBegin(&motor_pump);    // start motor_pump block
            CoBegin(&sequence_lite); // start sequence_lite block
            CoBegin(&heater);        // start heater block
        }
        funcblk motor_pump
        {
            OIL_PUMP = ON;
            
            waitfor(DelaySec(2L) OR NOT NOT_STOP OR NOT MACHINE_ON);

            if (NOT NOT_STOP OR NOT MACHINE_ON)
            {
                OIL_PUMP = OFF; // Didn't have chance to turn motor on 
            }
            else
            {
                MOTOR = ON;

                waitfor(NOT NOT_STOP OR NOT MACHINE_ON);

                MOTOR = OFF;
                if (NOT MACHINE_ON) 
                    OIL_PUMP = OFF; // If machine is off, Off pump now! 
                else
                {
                    waitfor(DelaySec(2L) OR NOT MACHINE_ON);

                    OIL_PUMP = OFF;
                }
            }
        }                    // end of motor_pump block

        funcblk sequence_lite
        {
            do
            {
                LITE1 = ON;

                waitfor(DelaySec(1L) OR NOT NOT_STOP OR NOT MACHINE_ON);

                if (NOT NOT_STOP OR NOT MACHINE_ON) 
                    break;
                LITE1 = OFF;
                LITE2 = ON;
                waitfor(DelaySec(1L) OR NOT NOT_STOP OR NOT MACHINE_ON);
                
                if (NOT NOT_STOP OR NOT MACHINE_ON) 
                    break;
                LITE2 = OFF;
                LITE3 = ON;
                waitfor(DelaySec(1L) OR NOT NOT_STOP OR NOT MACHINE_ON);
                
                if (NOT NOT_STOP OR NOT MACHINE_ON) 
                    break;
                LITE3 = OFF;
            } while (1);
            LITE1 = LITE2 = LITE3 = OFF;
        }                    // end of sequence_lite block

        funcblk heater
        {
            do
            {
                waitfor(THERMISTOR OR NOT NOT_STOP OR NOT MACHINE_ON);
                             // when cool, turn on heater
                if (NOT NOT_STOP OR NOT MACHINE_ON) 
                    break;
                HEATER_ON_OFF = ON;
                waitfor(NOT THERMISTOR OR NOT NOT_STOP OR NOT MACHINE_ON);
                             // when hot, turn off heater
                if (NOT NOT_STOP OR NOT MACHINE_ON) 
                    break;
                HEATER_ON_OFF = OFF;
            } while (1);
            HEATER_ON_OFF = OFF;
        }                    // end of heater block
    }
}



