#use "default.h"
#use "rtk.lib"

#if ((BOARD_TYPE==CPLC_BOARD) || (BOARD_TYPE==L_STAR))
#use cplc.lib
#endif

/*
	UIRTK.C

 - Uses a task of the real time kernel to drive the virtual drivers for
	the XP8200/universal input expansion card. Other tasks can use the virtual
	data for control and data handling. This program defaults to the first 2
	boards (i.e. index 0 and 1 for boards 0x040 and 0x041,respectively).

 - To observe a change in an input, simply use the appropriate jumper on header
	J2/J3/J4/J5 to pull the input up or down. Then evaluate the virtual driver
	variable's value in the watch window (eg: ui[0].UIN3).
 
 - The virtual driver function is ui_drivers().

 - Works with any board that has the PLCBUS.

 - If the PK2100/Rugged Giant/CPLC is used as the processor board, the virtual
 	driver can be set to read analog input. If the input voltage is higher than
 	the UHIGH threshold of a channnel, then the virtual input ui[j].UIN is set
 	to 1. If the voltage is less than ULOW threshold, the the virtual input
 	ui[j].UIN is set to 0.
   Connect DAV to DA on header H4, then connect the CPLC UEXP output to the DA
   wago connection.

 - Use the UIUNIVERSAL option for set_ui_inputmode(board_index, UIUNIVERSAL);

 - Alternatively, if #define UIBOARD_VDR is enabled, then the background
	routine that services the keypad and the lcd will automatically execute
	the function ui_drivers().

*/

/***Begin Globals real_time_kernel  */

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

#define RUNKERNEL
#define NTASKS 7

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

#define UIBOARD_VDVR
#define TESTMODE  UIUNIVERSAL
                        // just for testing
                        // UIDIGITAL for digital input mode
                        // UIUNIVERSAL for analog input mode
root main() 
{
    DI();
#if ((BOARD_TYPE==CPLC_BOARD) + (BOARD_TYPE==L_STAR))
    uplc_init();     // uplc_init handles the RTK for PK2100/CPLC
#ifndef UIBOARD_VDVR
    run_every(TASK0,1); // you can drive ui_drivers() with an RTK task
#endif
#else
    init_kernel();
    init_timer0(9216);   // use timer0 to drive the real time kernel
    run_every(TASK0,1);  // for the BL1200/Little PLC, the driver is run thru
                         // an RTK task
#endif

    run_every(TASK1,5);
    reset_pbus();
    reset_pbus_wait();
    
#if BOARD_TYPE==L_STAR
    reset_pbus_wait();  // do twice to accomodate the PK2200/Little Star
#endif    

    _uiLocateBrd();
#if (TESTMODE==UIUNIVERSAL) *(BOARD_TYPE==CPLC_BOARD)
    _uiSetIMode(0,UIUNIVERSAL);  // analog mode is only possible
    _uiSetIMode(1,UIUNIVERSAL);  // with the PK2100/CPLC
  // set the high threshold other than the defaults set at find_ui_board()
    ui[1].UHIGH0 = ui[0].UHIGH0 = up_uncal(1050);
    ui[1].UHIGH1 = ui[0].UHIGH1 = up_uncal(1300);
    ui[1].UHIGH2 = ui[0].UHIGH2 = up_uncal(1550);
    ui[1].UHIGH3 = ui[0].UHIGH3 = up_uncal(1800);
    ui[1].UHIGH4 = ui[0].UHIGH4 = up_uncal(2050);
    ui[1].UHIGH5 = ui[0].UHIGH5 = up_uncal(2300);
    ui[1].UHIGH6 = ui[0].UHIGH6 = up_uncal(2550);
    ui[1].UHIGH7 = ui[0].UHIGH7 = up_uncal(2800);
// set the low threshold
    ui[1].ULOW0 = ui[0].ULOW0 = up_uncal(1000);
    ui[1].ULOW1 = ui[0].ULOW1 = up_uncal(1250);
    ui[1].ULOW2 = ui[0].ULOW2 = up_uncal(1500);
    ui[1].ULOW3 = ui[0].ULOW3 = up_uncal(1750);
    ui[1].ULOW4 = ui[0].ULOW4 = up_uncal(2000);
    ui[1].ULOW5 = ui[0].ULOW5 = up_uncal(2250);
    ui[1].ULOW6 = ui[0].ULOW6 = up_uncal(2500);
    ui[1].ULOW7 = ui[0].ULOW7 = up_uncal(2750);
#else
    _uiSetIMode(0,UIDIGITAL); // digital mode is possible for
    _uiSetIMode(1,UIDIGITAL); // the BL1200/Little PLC and PK2100/CPLC
#endif

    EI();                       /* start running */
    backgnd();                  /* this runs after everything else */
}

/* ### new feature */
/* the following line changes the default function class to
   xmem and save the current setting */

   
indirect task0()
{        /* not currently used */
  int i;
  ui_drivers();     // run the virtual driver as a task
  hitwd();
}

indirect task1()   // write over combinations of inputs to the output
{
#if (TESTMODE==UIUNIVERSAL) * (BOARD_TYPE==CPLC_BOARD)
     use_analog();
#else
     use_digital();
#endif
}

indirect task2()
{
}

indirect task3()
{
}

indirect task4()
{
}

indirect task5()
{
}
indirect backgnd()
{
  while(1) runwatch();  // can monitor other states
}

int use_digital()
 {
  ui[1].OUT[0] = ui[1].DIG[0] && ui[1].DIG[15];
  ui[1].OUT[1] = ui[1].DIG[1] || ui[1].DIG[14];
  ui[1].OUT[2] = ui[1].DIG[2] && ui[1].DIG[15];
  ui[1].OUT[3] = ui[1].DIG[3] || ui[1].DIG[14];
  ui[1].OUT[4] = ui[1].DIG[4] && ui[1].DIG[15];
  ui[1].OUT[5] = ui[1].DIG[5] || ui[1].DIG[14];
  ui[0].OUT[0] = ui[0].DIG[0] && ui[0].DIG[15];
  ui[0].OUT[1] = ui[0].DIG[1] || ui[0].DIG[14];
  ui[0].OUT[2] = ui[0].DIG[2] && ui[0].DIG[15];
  ui[0].OUT[3] = ui[0].DIG[3] || ui[0].DIG[14];
  ui[0].OUT[4] = ui[0].DIG[4] && ui[0].DIG[15];
  ui[0].OUT[5] = ui[0].DIG[5] || ui[0].DIG[14];
 }

int use_analog()
{
  ui[0].OUT[0] = ui[0].UIN0 && ui[0].UIN15;
  ui[0].OUT[1] = ui[0].UIN1 || ui[0].UIN14;
  ui[0].OUT[2] = ui[0].UIN2 && ui[0].UIN15;
  ui[0].OUT[3] = ui[0].UIN3 || ui[0].UIN14;
  ui[0].OUT[4] = ui[0].UIN4 && ui[0].UIN15;
  ui[0].OUT[5] = ui[0].UIN5 || ui[0].UIN14;
  ui[1].OUT[0] = ui[1].UIN0 && ui[1].UIN15;
  ui[1].OUT[1] = ui[1].UIN1 || ui[1].UIN14;
  ui[1].OUT[2] = ui[1].UIN2 && ui[1].UIN15;
  ui[1].OUT[3] = ui[1].UIN3 || ui[1].UIN14;
  ui[1].OUT[4] = ui[1].UIN4 && ui[1].UIN15;
  ui[1].OUT[5] = ui[1].UIN5 || ui[1].UIN14;
}
