/*
    XDemo11: Real-time I/O control

    Compiler: BC++ 3.1
    Compile mode: large
    Project: user.c
             v7000.c
             vModbus.c           [after vcom3002.lib]
             ..\Lib\7186EL.Lib
             ..\Lib\tcp_dm32.lib
             ..\Lib\VcomNNNN.Lib, with NNNN being the lib file's version.


    19i, 19I  -> read D/I form address 0
    19o, 19O  -> D/O to address 0

    This demo shows complex real time DI/DO operation in UserLoopFun.

    Hardware: uPAC-7188EX + DI/DO expansion board

    [Dec 18, 2008] by Liam
*/

#include <string.h>
#include <stdio.h>
#include <conio.h>
#include "..\lib\7186e.h"
#include "..\lib\Tcpip32.h"
#include "..\lib\vxcomm.h"

unsigned char DI,DO;
char cVal[80];

void UserCount(void)
{
    /*
    User's timer trigger function.
    Please refer to XDemo04 for detail description.
    Please refer to XDemo09 for example code.
    */
}

void UserInit(void)
{
    /*
    Initialize user's program.
    Please refer to XDemo04 for detail description.
    Please refer to XDemo09 for example code.
    */
    
    InitLib();
}

void UserLoopFun(void)
{
    /*
    VxComm.exe will call this function every scan time
    real-time I/O control function
    DO0=!DI0, DO1=(DI1+DI2), DO2=(DI3)
    DO3 ~ DO6: control by host-pC
    */

    DI=inportb(1);      // read DI (for X107)
    //DI=inportb(0);    // read DI (for other expansion boards)

    if(DI & (0x01<<0))
        DO=DO&0xfe;     // DO0=!DI0
    else
        DO=DO | 1;

    if ((DI & (0x01<<1)) || (DI&4))
        DO=DO | 2;      // DO1=(DI1+DI2)
    else
        DO=DO & 0xfd;

    if (DI & (0x01<<2))
        DO=DO | 4;      // DO2=DI3
    else
        DO=DO & 0xfb;

    outportb(0, DO);    // write value to DO0, DO1 and DO2
}



int UserCmd(unsigned char *Cmd,unsigned char *Response)
{
    /*  
    Xserver executes this function when received a package 
    form TCP port 10000 and the first two bytes are "19".
    
    Funtion of Xserver, Please refer to XDemo04 for detail description.
    */  
    
    int iAddr=1;    // for X107
    //int iAddr=0;  // for other expansion boards
    char DoVal;
    
    switch(Cmd[0])
    {
        case 'i':
        case 'I':
            DI=inportb(iAddr);
            sprintf(cVal,"%x",DI);
            break;
        case 'o':
        case 'O':
            sscanf(Cmd+1,"%x",&DoVal);
            sprintf(cVal,"%x",DoVal);
            DoVal=DoVal&0x78;
            DO=DO | DoVal;
            outportb(0,DoVal);
            break;
        default:
            return 0;       // return Error
    };
    strcpy(Response,cVal);
    return 1;               // return OK
}

int VcomUserBinaryCmd(TCPREADDATA *p)
{
    /* 
    VXCOMM.EXE 2.6.12(04,Sep,2001) or later will support this function.

    Xserver executes this function when received a package 
    form TCP port 10000 and the first two bytes are "23".
    
    Please refer to XDemo04 for detail description.
    Please refer to XDemo23 for example code.
    */
    return 1;   /* any value will be accept */
}

int VcomCmdUser(TCPREADDATA *p)  
{ 
    /*
    VCOM3005 (Feb,22,2002) or later will call this function for PortUser.
    When packets received by TCP PORT PortUser(user defined) 
    of 7188E/8000E, Xserver will call this function.

    Please refer to XDemo04 for detail description.
    */
    VcomSendSocket(p->Socket,p->ReadUartChar,p->Length);
    return 1;   /* any value will be accept */  
}

void PortUserStart(int skt)
{
    /* 
    XS8_3200.Lib Version 3.2.00 (20,Apr,2004) 
    or later version supports this function.
    
    When a TCP/IP client connects to the 7188E/8000E via the user's 
    defined port(PortUser), the Xserver calls the function once.

    Please refer to XDemo04 for detail description.
    */
    
    skt=skt; //do nothing
}
  
void Port9999Start(int skt)
{
    /* 
    XS8_3200.Lib Version 3.2.00 (20,Apr,2004) 
    or later version supports this function.
    
    When a TCP/IP client connects to the 7188E/8000E TCP port 9999, 
    the Xserver calls the function once.
 
    Please refer to XDemo04 for detail description.
    */
    
    skt=skt; //do nothing
}
 
void Port502Start(int skt)
{
    /* 
    XS8_3200.Lib Version 3.2.00 (20,Apr,2004) 
    or later version supports this function.
    
    When a TCP/IP client connects to the 7188E/8000E TCP port 502, 
    the Xserver calls the function once.
    
    Please refer to XDemo04 for detail description.
    */
    
    skt=skt; //do nothing
}
