/* XFRdir: i7188EF0-16 Xserver demo 

   Compiler: BC++ 3.1 ,TC++ 3.0, TC++ 1.01
   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.

   19ri n, 19RI n       -> read D/I value(hex) from DI group n(hex)
   19wo n val, 19O n val    -> output D/O value(hex) to DO group n(hex)
   19ro n, 19RO n       -> read D/O readback value(hex) from group n(hex)
   n  ==> group number (0~7)
   val==> One group value (0000~FFFF)

 7188EX _EF016 ==> 16 groups (8 DO groups/8 DI groups)
 DO address
    Group   Address Write
    0   0x0 outpw(0x0,????)
    1   0x2 outpw(0x2,????)
    2   0x4 outpw(0x4,????)
    3   0x6 outpw(0x6,????)
    4   0x8 outpw(0x8,????)
    5   0xA outpw(0xA,????)
    6   0xC outpw(0xC,????)
    7   0xE outpw(0xE,????)
 ????==> DO value (0000~FFFF) 
  DI address
    Group   Address Reading
    0   0x0 inpw(0x0)
    1   0x2 inpw(0x2)
    2   0x4 inpw(0x4)
    3   0x6 inpw(0x6)
    4   0x8 inpw(0x8)
    5   0xA inpw(0xA)
    6   0xC inpw(0xC)
    7   0xE inpw(0xE)

     Hardware: i7188EF-016 + FR2053 + FR2057
   
   Refer FR_Net\7188ef for more details regarding i-7188EF-016
   Refer FR_Net\IO_Module for more details regarding FR2053 and FR2057

   [Dec 18, 2008] by Liam 
*/

#include <string.h>
#include "..\lib\7186e.h"
#include "..\lib\tcpip32.h"
#include "..\lib\vxcomm.h"

WORD gwOutVal;  //DO value
void UserCount(void)
{
/*
    // user's timer trigger function
    //
    // In this function, user cannot use any function that will use the hardware signal "clock",
    // Such as:
    //  1. ClockHigh(),ClockLow(), ClockHighLow(),
    //  2. Any EEPROM functions.
    //  3. Any 5DigitLed functions.
    //  4. Any NVRAM function.
    //  5. Any RTC function.(GetTime(),SetTime(),GetDate(),SetDate())
    //
    // refer to demo9 for example code 
*/
}

void UserInit(void)
{
/*
    In this function, user CAN:
    1. initialize user's program.
    2. set time interval for calling UserCount().
    3. set initial value of I/O or variables for UserLoopFun().
    4. set initial value of I/O or variables for another functions.
    5. change the default TCP PORT 10000/9999/502 to others value. [after vcom3004.lib]
       Syntax:
        Port10000=newport_10000;  for calling UserCmd       (user.c)
        Port9999=newport_9999;    for calling VcomCmd7000   (v7000.c)
        Port502=newport_502;      for calling VcomCmdModbus (vModbus.c) [after vcom3002.lib]
        PortUser=newport_User;    for calling VcomCmdUser   (user.c)    [after vcom3005.lib]
        
        Default port value:
        Port10000=10000;
        Port9999=9999;
        Port502=502;
        PortUser=0;
        If the port value is 0, Xserver will not 
        listen that port. That means the port will 
        be disable.
        
    Please refer to demo9 & demo11 for example code
*/  
    InitLib();
    
    gwOutVal=0;
    SetBaudrate(1, 115200L); //COM1 debug port
    SetDataFormat(1, 8, 0, 1);
}

void UserLoopFun(void)
{
    // VxComm.exe will call this function every scan time
    // refer to demo11 for scan-time evaluation
}

char cVal[80];
int UserCmd(unsigned char *Cmd,unsigned char *Response)
{
    // user's command interpreter
    // refer to all demo
    // Maximum length of Cmd is 1458 bytes.
    // Maximum length of Response is 1024 bytes.
    
    int iAddr;
    WORD wVal;

    strlwr(Cmd);
    if(Cmd[0]=='r') //Read DI/DO readback
    {
        sscanf(Cmd+2, "%x", &iAddr);  
        printCom1("string:%s, iAddr=%d\r\n", Cmd,iAddr); //Debug message
        switch(Cmd[1])
        {
            case 'i':  // inp command: i 0 or I0
                wVal=inpw(iAddr*2);
                sprintf(cVal,"%x",wVal);
                break;
            case 'o':
                sprintf(cVal,"%x",gwOutVal);
                break;
            default:
                return 0;           // return error
        }      
    }
    else if(Cmd[0]=='w'&& Cmd[1]=='o')  //write DO
    {
        sscanf(Cmd+2,"%x %x", &iAddr, &wVal);
        sprintf(cVal,"%x", wVal);
        outpw(iAddr*2, wVal);
        gwOutVal=wVal;
    }
    else
        return 0;                   // return ERROR
        
    strcpy(Response, cVal);  // return I/O value
    return 1;   
}

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

        TCP PORT 10000, command 23 will call this function.
        user can get the following message:
        p->ReadUartChar : the buffer store the command data(include "23")
                          Maximum length of p->ReadUartChar is 32767 bytes.
        p->Length : the command data length(include the two byte "23")
        p->Socket : the socket number that receives the command, that is, when the user function wants
                to return a message to the client, just use the socket to send data.
                usage:  VcomSendSocket(p->Socket,pdata,datalength);
 */
    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.
    user can get the following message:
    p->ReadUartChar : the buffer store the command data.
                      Maximum length of p->ReadUartChar is 32767 bytes.
    p->Length : the command data length.
    p->Socket : the socket number that receive the command, that is when the user function wants 
                return message to the client, just use the socket to send data.
                usage:  VcomSendSocket(p->Socket,pdata,datalength);
    */
  
    /* here just send back the command to the client. */
    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.
    
        You can use function VcomSendSocket to send a message to the client 
        when a connection is established.
    
    For example:
        VcomSendSocket(skt,"Connection is established.",26); //return 26 bytes.
 
        skt: socket number assigned to the TCP/IP client.
    */
    
    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.
    
        You can use function VcomSendSocket to send a message to the client 
        when a connection is established.
        
    For example:
        VcomSendSocket(skt,"Connection is established.",26); //return 26 bytes.
 
        skt: socket number assigned to the TCP/IP client.
    */
    
    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.
    
        You can use function VcomSendSocket to send a message to the client 
        when a connection is established.
    
    For example:
        VcomSendSocket(skt,"Connection is established.",26); //return 26 bytes.
 
        skt: socket number assigned to the TCP/IP client.
    */
    
    skt=skt; /*do nothing*/
}