#use "default.h"

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

/*
	UIVDVR.C
	
   - Same as uiexpio.c except that we use the virtual driver for boards
	  0 and 1 to handle the inputs and outputs. ui_drivers() is the virtual
	  driver for boards 0 and 1. 

	- Works with any board that has the PLCBUS.
	
DIGITAL INPUT CONFIGURATION

  - For digital input, connect jumper DAV to VL on Header H4. The threshold
    is set with
         Vthresh = CV*( R5/(R4+R5)), where R4=R5=10k,  Vthresh = 0.5 * CV

  - Set the board as digital with:
         _uiSetIMode(board_index, UIDIGITAL).

  - Virtual data are accessed as:
       ui[j].OUT[i]
       ui[j].DIG[i]
                    where j= 0 for board 0 or 0x040
                          j= 1 for board 1 or 0x041
                          i= 0 to 15 for input
                          i= 0 to 5  for output

  - The library supports only the first two boards for virtually driven io's.
    it can be easily modified to handle more boards if the user wants it.

UNIVERSAL INPUT CONFIGURATION

  - If the PK2100/Rugged Giant is used as the processor board, the virtual
    driver can be set to read analog input.

  - Each input channel has a UHIGH value, a ULOW value and its state ui[j].UINk.
    If the input voltage becomes higher than the UHIGH threshold of a channel,
    then the kth virtual input ui[j].UINk is set to 1. If the voltage becomes
    lower than the ULOW threshold, the kth virtual input ui[j].UINk is set to 0.
    Change in state has to persist for two executions of the virtual driver
    before a change is recorded.

  - Virtual Data are accessed as:
       ui[j].UHIGHx
       ui[j].ULOWx
       ui[j].UINx        where j = 0 for board 0 or 0x040
                               j = 1 for board 1 or 0x041
                               x = 0 to 15 for inputs 0-15

  - Connect DAV to DA on Header H4 and connect the PK2100/RUGGED Giant UEXP
    output to DA wago connection.

  - Use the UIUNIVERSAL option with:
       _uiSetIMode(board_index, UIUNIVERSAL);
*/

//#define TESTMODE UIDIGITAL
#define TESTMODE UIUNIVERSAL // for testing only
                             // UIDIGITAL for digital input mode.
                             // UIUNIVERSAL for analog input mode.
#define UIBOARD_VDVR         // Only useful with the PK2100/CPLC. Will make
                             // background routine drive ui_drivers().

main()  
{
  char c;
#if ( (BOARD_TYPE==CPLC_BOARD) + (BOARD_TYPE==L_STAR))
      uplc_init();
#endif
  reset_pbus();
  reset_pbus_wait();
#if BOARD_TYPE==L_STAR
    reset_pbus_wait(); // do twice to accommodate the PK2200/Little Star
#endif      
  _uiLocateBrd();    // locate the ui boards in the bus

#if ((BOARD_TYPE==CPLC_BOARD)*(TESTMODE==UIUNIVERSAL))
	// exposed calibration for EXPOUT.
	// set the high threshold other than the defaults set with _uiLocateBrd()
    _uiSetIMode(0,UIUNIVERSAL);
    _uiSetIMode(1,UIUNIVERSAL);
    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);
   _uiSetIMode(1,UIDIGITAL);
#endif
  printf("Press F4 to make keyboard input active as STDIO (for DC-DOS).\n");
  printf("\nHit 'a' to turn ON outputs 0-5 and 16-21.");
  printf("\nHit 'b' to turn OFF outputs 0-5 and 16-21.");
  printf("\nHit 'c' to read digital channels 0-15 and 16-31.");
  printf("\nHit 'd' for universal input (UIUNIVERSAL has to be used.)\n");
  printf("\nIf board is not present, the virtual driver will ignore it.\n");

  while(1)
  {
  		hitwd();
      while(kbhit()==0)
      {
      	hitwd();
         runwatch();  // monitor other variables 
#if BOARD_TYPE == CPLC_BOARD
#ifndef UIBOARD_VDVR
         ui_drivers();  // virtual driver is running
#endif
       // if UIBOARD_VDVR is defined, the background routine for the lcd and
      //  keypad of the PK2200/CPLC will also run ui_drivers() every 25ms.
#else
         ui_drivers();  // BL1200/Little PLC has no background to run this
#endif

      }

      c = getchar();
      switch(c)
      {
         case 'a':
            printf("OUTPUTS are ON.\n");
            ui[0].OUT[0] = ui[0].OUT[1] = ui[0].OUT[2] = 1;
            ui[0].OUT[3] = ui[0].OUT[4] = ui[0].OUT[5] = 1;
            ui[1].OUT[0] = ui[1].OUT[1] = ui[1].OUT[2] = 1;
            ui[1].OUT[3] = ui[1].OUT[4] = ui[1].OUT[5] = 1;
            break;
         case 'b':
            printf("OUTPUTS are OFF.\n");
            ui[0].OUT[0] = ui[0].OUT[1] = ui[0].OUT[2] = 0;
            ui[0].OUT[3] = ui[0].OUT[4] = ui[0].OUT[5] = 0;
            ui[1].OUT[0] = ui[1].OUT[1] = ui[1].OUT[2] = 0;
            ui[1].OUT[3] = ui[1].OUT[4] = ui[1].OUT[5] = 0;
            break;
         case 'c':
        		printf("DIGITAL chans 0-15 for board 0 (0x040)\n");
            printf("%d%d%d%d%d%d%d%d   %d%d%d%d%d%d%d%d\n",
            ui[0].DIG[0],ui[0].DIG[1],ui[0].DIG[2],
            ui[0].DIG[3],ui[0].DIG[4],ui[0].DIG[5],
            ui[0].DIG[6],ui[0].DIG[7],ui[0].DIG[8],
            ui[0].DIG[9],ui[0].DIG[10],ui[0].DIG[11],
            ui[0].DIG[12],ui[0].DIG[13],ui[0].DIG[14],
            ui[0].DIG[15]);
            printf("DIGITAL chans 16-31 for board 1 (0x041) \n");
            printf("%d%d%d%d%d%d%d%d   %d%d%d%d%d%d%d%d\n",
            ui[1].DIG[0],ui[1].DIG[1],ui[1].DIG[2],
            ui[1].DIG[3],ui[1].DIG[4],ui[1].DIG[5],
            ui[1].DIG[6],ui[1].DIG[7],ui[1].DIG[8],
            ui[1].DIG[9],ui[1].DIG[10],ui[1].DIG[11],
            ui[1].DIG[12],ui[1].DIG[13],ui[1].DIG[14],
            ui[1].DIG[15]);
            break;
#if (TESTMODE==UIUNIVERSAL)*(BOARD_TYPE==CPLC_BOARD)
         case 'd':
       		printf("UNIVERSAL chans 0-15 for board 0 (0x040)\n");
            printf("%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d\n",
            ui[0].UIN0,ui[0].UIN1,ui[0].UIN2,
            ui[0].UIN3,ui[0].UIN4,ui[0].UIN5,
            ui[0].UIN6,ui[0].UIN7,ui[0].UIN8,
            ui[0].UIN9,ui[0].UIN10,ui[0].UIN11,
            ui[0].UIN12,ui[0].UIN13,ui[0].UIN14,
            ui[0].UIN15);
            printf("UNIVERSAL chans 16-31 for board 1 (0x041) \n");
            printf("%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d\n",
            ui[1].UIN0,ui[1].UIN1,ui[1].UIN2,
            ui[1].UIN3,ui[1].UIN4,ui[1].UIN5,
            ui[1].UIN6,ui[1].UIN7,ui[1].UIN8,
            ui[1].UIN9,ui[1].UIN10,ui[1].UIN11,
            ui[1].UIN12,ui[1].UIN13,ui[1].UIN14,
            ui[1].UIN15);
            break;
#else
         case 'd':
            printf("ANALOG OPTION IS NOT POSSIBLE OR NOT USED.\n");
            break;
#endif
         default: printf("Try 'a', 'b', 'c' or 'd'.\n");
            break;   
         }
    }
}