/*
    XDemo13: pulse width meansurement

    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.

    19~!@#$  -> Any non-null command will be accepted.

    LoopFun reads the D/I signal. If signal is changed, records time ticks
    and calculates signal width.

    Hardware: uPAC-7186EX + DI 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 long High_t1, High_t2, Low_t1, Low_t2, High_t, Low_t;
char c_cnt[80], now, old;

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();
    
    High_t1=0;  // Old time ticks (signal change)
    High_t2=0;  // Now time ticks
    Low_t1=0;   // Old time ticks (signal change)
    Low_t2=0;   // Now time ticks

    if (inportb(1) & 0x01)      // DI is High now (for X107)
//  if (inportb(0) & 0x01)      // DI is High now (for other expansion boards)
    {
        old=1;
        High_t1=High_t2=(GetTimeTicks());   //get High initial time
    }
    else    // D/I is low now
    {
        old=0;
        Low_t1=Low_t2=(GetTimeTicks());     //get Low initial time
    }
}

void UserLoopFun(void)
{
    /*
    VxComm.exe will call this function every scan time
    Please refer to XDemo11 for Real-time I/O control
    */    

    if (inportb(1) & 0x01)          // DI is High now (for X107)
//  if (inportb(0) & 0x01)          // DI is High now (for other expansion boards)
    {
        if (old)            // High become High
        {
            High_t2=(GetTimeTicks());
        }
        else                // Low become High
        {
            High_t1=(GetTimeTicks());   //reset High inital time
            old=1;
            Low_t=Low_t2-Low_t1+1;      //calculate total Low time
        }
    }
    else                    // D/I is low now
    {
        if (old)            // High become Low
        {
            Low_t1=(GetTimeTicks());    //reset Low inital time
            old=0;
            High_t=High_t2-High_t1+1;   //calculate total High time
        }
        else                // Low become Low
        {
            Low_t2=(GetTimeTicks());
        }
    }
}

char cVal[80];

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.
    */  

    if (Cmd[0])     // Not Null command
    {
        sprintf(cVal, "%lu %lu", High_t, Low_t);
        strcpy(Response, cVal);     //return High and Low time
        return 1;       // return OK
    }
    
    return 0;        // return ERROR
}

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
}
