/* DEMO5: Add callback function for COM port File name: user.c Compile mode: large Last time update: Jan/02/2012 By: Tim Tsai. */ #include #include #include "module1.h" /*----------------------------------------------------------------------------*/ static long lUserCnt=0; /*----------------------------------------------------------------------------*/ void UserCount(void) { /* // user's timer trigger function // // In this function 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 */ lUserCnt++; } /*----------------------------------------------------------------------------*/ void UserEnd(void) { Print("Call UserEnd().\r\n"); StopUserTimerFun(); } /*----------------------------------------------------------------------------*/ void MyComCallbackFun_2(pCOMPORT pComPort, int mode); /*----------------------------------------------------------------------------*/ void UserInit(void) { /* In this function CAN DO: 1. user's initial function 2. timer initialized for UserCount() 3. I/O or variables initialized for UserLoopFun() 4. I/O or variables initialized for User's functions in this file 5. change the default TCP PORT 10000/9999/502 to others value by: Port10000=newport_10000; Port9999=newport_9999; Port502=newport_502; Please refer to demo9 & demo11 for example code [02/19/2002] add PortUser 6. PortUser=newport_User; (by default PortUser=0.) *** If Port9999/Port502/PortUser=0, The main program will not listen these port. *** */ pCOMPORT pCom; int Port,port; UserProgramName="MyDemo5"; UserProgramVersion="V1.0[" __DATE__ "]"; InstallUserTimerFunction_ms(1,UserCount); /* 底下是使用 COM port 有關的設定(以 COM2 為例) 如果是要用 COM0 請參考 demo7。 */ port=COM2; // COM2 的 index 為 1 時使用 port Port=port+1; // COM2 的 index 為 2 時使用 Port pCom=&LocalCom[Port]; pCom->EndChar=0; // modbus RTU 沒有特定的結束字元。 #if 0 if((ComPortBufferedDataSize[port] < 0) || (ComPortBufferedDataSize[port] > ComBufferSize[port]) ){ ComPortBufferedDataSize[port]=ComBufferSize[port]; } #endif // pCom->TriggerLevel=ComPortBufferedDataSize[port]; //預設值就是 buffer size。 #if 0 //底下幾項不用設定 pCom->StartTimeTicks=0L; pCom->LastTimeTicks=0L; pCom->MasterStartTimeTicks=0L; #endif pCom->MasterTimeout=2L; // MODBUS/RTU 設為至少4個字元的長度。 pCom->CallbackFun=MyComCallbackFun_2; //設定新的 call back function pCom->Size=0; } /*----------------------------------------------------------------------------*/ void UserLoopFun(void) { /* // VxComm.exe will call this function in every scan time // refer to demo11 for scan-time evaluation */ } /*----------------------------------------------------------------------------*/ int UserCmd(unsigned char *Cmd,unsigned char *Response) { /* // user's command interpreter // refer to all demo */ // _dPrint("%s",Cmd); if (Cmd[0]){ /* Not Null command */ if(Cmd[0]=='0') { DisableCom(1); strcpy(Response,"Disable COM1 OK"); } else if(Cmd[0]=='1') { EnableCom(1); strcpy(Response,"Enable COM1 OK"); } else { long tmpl; _asm cli; tmpl=lUserCnt; _asm sti; sprintf(Response,"Current UserCnt=%lu\r\n",tmpl); } return 1; /* return OK */ } return 0; /* return ERROR */ } /*----------------------------------------------------------------------------*/ /* typedef struct t_TcpReadData{ int Comport; int Socket; int Length; char* ReadUartChar; }TCPREADDATA; */ int VcomSendSocket(int skt,char *data,int cnt); /*----------------------------------------------------------------------------*/ 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") p->Length : the command data length(include the two byte "23") p->Socket : the socket number that receive the command, that is when the user function want return message to the client, just use the socket to send data. use: VcomSendSocket(p->Socket,pdata,datalength); */ /* just echo back*/ VcomSendSocket(p->Socket,p->ReadUartChar,p->Length); } /*----------------------------------------------------------------------------*/ int VcomCmdUser(TCPREADDATA *p) { /* VCOM3005 or later will call this function for PortUser. when socket from TCP PORT PortUser will call this function. user can get the following message: p->ReadUartChar : the buffer store the command data. p->Length : the command data length. p->Socket : the socket number that receive the command, that is when the user function want return message to the client, just use the socket to send data. use: VcomSendSocket(p->Socket,pdata,datalength); */ /* here just send back the command come from PortUser. */ VcomSendSocket(p->Socket,p->ReadUartChar,p->Length); } /*----------------------------------------------------------------------------*/ void Port9999Start(int skt) { TcpPrint(skt,1,"Welcome connect to Port %u\r\n",Port9999); } /*----------------------------------------------------------------------------*/ void Port502Start(int skt) { TcpPrint(skt,1,"Welcome connect to Port %u\r\n",Port502); } /*----------------------------------------------------------------------------*/ void PortUserStart(int skt) { TcpPrint(skt,1,"Welcome connect to Port %u\r\n",PortUser); } /*----------------------------------------------------------------------------*/ void MyComCallbackFun_2(pCOMPORT pComPort, int mode) { int Port=pComPort->Port; int skt; int port; int i,err; #if _DEBUG_COM_ > 0 XS_dPrint("[COM%d:%d:@%lu:%d]",Port,mode,CurrentLoopTimeTicks,pComPort->Size);//[2007/08/03]測試 #endif switch(mode){ case 0: // 超過 Timeout 時間沒再收到字元 case 1: // 收到 EndChar case 2: // 收到字元個數到達 TriggerLevel case 3: // buffer 已經滿了 case 4: case 5: // bTimeOut 是 1 (16c550/16c950 才有) DoComReply: port=Port-1; // 在此處理回應訊息 pComPort->Size=0; // 處理完要把 Size 設成 0。 break; default: pComPort->Size=0; break; } }