/*
	LADDERC.C

	This sample illustrates the use of the Dynamic C ladder C construct. It
	also illustrates the use of the virtual drivers for i/o and the virtual
	timers for timing. The timer reload values are set in software.

	Following are actions performed by this sample.
	
     - motor_pump()
         - when started, the pump comes on first
         - the motor comes on after the specified delay
         - when stop, the motor stops right away.
         - the pump stops after a specified delay.
         - a machine off shuts down everything.

     - sequence_lite()
         - when started, lite 1 comes on
         - after some delay, lite1 is off, lite2 comes on
         - after some delay, lite2 is off, lite3 comes on
         - after some delay, lite3 is off, lite1 comes on
         - a stop or a machine_off shuts down everything.

      - heater()
         - universal input U1IN is connected across a thermistor
         - when the voltage read is high ( thermistor is cool)
            the heater is turn on with OUT3.
         - when the voltage read is low ( thermistor is hot)
            the heater is turn off with OUT3.

      - Runs on Z-World's Demo Unit Two
*/

#use "default.h"
#use cplc.lib
#use gate_p.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

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

#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       // start timer1
#define T1_DONE    T1O       // timer1 is done
#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         // driver for light1
#define LITE2   OUT9         // driver for light2
#define LITE3   OUT10        // driver for light3

#define HEATER_ON_OFF  OUT3  // driver for a coil heater

#if BOARD_TYPE==CPLC_BOARD
#define THERMISTOR U1IN      // thermistor voltage read
#elif BOARD_TYPE==L_STAR
#define THERMISTOR DIGIN9    // mimic thermistor output with DIGIN9
#endif

main()
{
    uplc_init();
    reset_timers();          // reset the state of the virtual timers
    T1RLD = 40;              // 1 count is 25 ms >> 40 x 25ms = 1 sec
    T2RLD = 40;
    T3RLD = 40;
    T4RLD = 40;
    T5RLD = 40;

#if BOARD_TYPE==CPLC_BOARD
    U1HIGH = up_uncal(8000); // high threshold is 8 volts
    U1LOW  = up_uncal(6000); // low threshold is 6 volts
#endif

    while (1)                // infinite loop
    {
        runwatch();          // monitor with the watch window
        motor_pump();
        sequence_lite();     // can actually run more than one ladderc block
                             // as long as io's don't have any conflicts.
        heater();
    }

}

int motor_pump(void)
{
    OIL_PUMP = (OIL_PUMP OR START) AND MACHINE_ON AND NOT T2_DONE;
    
    START_T1 =  OIL_PUMP AND MACHINE_ON AND NOT_STOP AND NOT T1_DONE;

    MOTOR    = (T1_DONE OR MOTOR) AND NOT_STOP AND MACHINE_ON;

    START_T2 = (NOT NOT_STOP OR START_T2) AND MACHINE_ON AND NOT T2_DONE;
}

int sequence_lite(void)
{
    LITE1 = (START OR T5_DONE OR LITE1) AND 
            NOT_STOP AND MACHINE_ON AND NOT T3_DONE;

    START_T3 = LITE1;

    LITE2 = (T3_DONE OR LITE2) AND NOT_STOP AND MACHINE_ON AND NOT T4_DONE;

    START_T4 = LITE2;

    LITE3 = (T4_DONE OR LITE3) AND NOT_STOP AND MACHINE_ON AND NOT T5_DONE;
    
    START_T5 = LITE3;
}

int heater(void)
{
    char start_heating;
    start_heating = (start_heating OR START) AND MACHINE_ON AND NOT_STOP;
    HEATER_ON_OFF = start_heating AND MACHINE_ON AND THERMISTOR;
}

