www.pudn.com > IEC104_codeamaterial.rar > extios_h.c, change:2010-09-21,size:7558b


/*------------------------------------------------------------------------ 
 Module:		extios_h.c 
 Author:		 
 Project:		 
 Creation Date:  
 Description:	 
------------------------------------------------------------------------*/ 
 
#include <stdlib.h> 
#include <string.h> 
#include "syscfg.h" 
#include "sys.h" 
#include "pcol.h" 
#include "extiopub.h" 
#include "extios_h.h" 
 
static DWORD SearchOneFrame(BYTE *Buf, int Len) 
{ 
	VExtIoFrmHead *pHead; 
 
	if (Len<sizeof(VExtIoFrmHead)+1)  return(PCOL_FRAME_LESS); 
		 
	pHead = (VExtIoFrmHead *)Buf; 
 
	if (pHead->byCode != EXTIO_CODE)  return(PCOL_FRAME_ERR|1); 
 
	if ((pHead->byAddr != EXTIO_BCADDR) && (pHead->byAddr != g_Sys.AddrInfo.wAddr))  return(PCOL_FRAME_ERR|1); 
 
	if (pHead->byLen > EXTIO_MAXFRM_LEN) return(PCOL_FRAME_ERR|1); 
 
	if (Len < (pHead->byLen+1)) return(PCOL_FRAME_LESS); 
	 
	if (*(Buf+pHead->byLen) != Bch(Buf,pHead->byLen)) return(PCOL_FRAME_ERR|1); 
	 
	return(PCOL_FRAME_OK|(pHead->byLen+1));	 
} 
 
static void SendFrameHead(VExtIoSH *pBus, BYTE fmType, BYTE fmFun, BYTE fmCtrl) 
{ 
	VExtIoFrmHead *pRec = (VExtIoFrmHead *)pBus->Col.RecFrm.pBuf; 
	VExtIoFrmHead *pSend = (VExtIoFrmHead *)pBus->Col.Send.pBuf; 
 
	pBus->Col.Send.wReadPtr  = 0; 
	pSend->byCode = EXTIO_CODE; 
	pSend->byAddr = (BYTE)g_Sys.AddrInfo.wAddr;	 
    if (fmCtrl & EXTIO_CTRL_MASTER)	 
		pSend->byCnt = ++pBus->byCnt; 
	else 
		pSend->byCnt = pRec->byCnt;		 
	pSend->byType = fmType; 
	pSend->byFun = fmFun; 
	pSend->byCtrl = fmCtrl; 
	 
    pBus->Col.Send.wWritePtr=sizeof(VExtIoFrmHead); 
} 
 
static void SendFrameTail(VExtIoSH *pBus, BYTE fmPrio) 
{   
	VExtIoFrmHead *pSend = (VExtIoFrmHead *)pBus->Col.Send.pBuf; 
	BYTE lrcCode; 
	 
    pSend->byLen = (BYTE)pBus->Col.Send.wWritePtr; 
     
    lrcCode = Bch(pBus->Col.Send.pBuf,pBus->Col.Send.wWritePtr); 
 
    pBus->Col.Send.pBuf[pBus->Col.Send.wWritePtr++] = lrcCode; 
     
	DoSend(&pBus->Col, (pSend->byCtrl<<24)|(g_Sys.AddrInfo.wAddr<<16)|(fmPrio<<8)|0); 
}  
 
 
static void Login(VExtIoSH *pBus, BYTE fmFun, BYTE fmCtrl) 
{ 
	VPcolCommBuf *Send = &pBus->Col.Send; 
	 
	SendFrameHead(pBus, EXTIO_TYPE_LOGIN, fmFun, fmCtrl); 
	memcpy(Send->pBuf+Send->wWritePtr, &g_Sys.AddrInfo, sizeof(struct VPExtIoAddr)); 
	Send->wWritePtr += sizeof(struct VPExtIoAddr); 
	SendFrameTail(pBus, FRM_PRIO_LEV6); 
} 
 
static void HBeat(VExtIoSH *pBus) 
{	 
	SendFrameHead(pBus, EXTIO_TYPE_HBEAT, EXTIO_FUN_DATA, EXTIO_CTRL_MASTER); 
	SendFrameTail(pBus, FRM_PRIO_LEV1); 
} 
 
static void KillMe(VExtIoSH *pBus, DWORD errcode) 
{ 
	tmEvCancle(pBus->Col.nId); 
	commCtrl(pBus->Col.nId, CCC_CHIP_CTRL|CHIP_OFF, 0); 	 
	SysSetErr(errcode); 
} 
 
#ifdef INCLUDE_YX 
 
static void SendDi(VExtIoSH *pBus) 
{	 
    int len; 
	 
	VPcolCommBuf *Send = &pBus->Col.Send; 
	 
	SendFrameHead(pBus, EXTIO_TYPE_DI, EXTIO_FUN_DATA, EXTIO_CTRL_MASTER); 
	diValueRead(&len, (WORD *)(Send->pBuf+Send->wWritePtr)); 
	Send->wWritePtr += len; 
	SendFrameTail(pBus, FRM_PRIO_LEV0); 
 
	pBus->byDiCnt = pBus->byCnt; 
} 
 
#endif 
static void ProcLogin(VExtIoSH *pBus, VExtIoFrmHead *pRec) 
{ 
	BYTE *pcode; 
	struct VPExtIoAddr *pAddr; 
 
	if (pRec->byFun == EXTIO_FUN_CONF) 
	{ 
		pAddr = (struct VPExtIoAddr *)(pRec+1);	 
		pcode = (BYTE *)(pAddr+1); 
 
		//if (*pdev_type != TYPE_BACK) return; 
		if (*pcode)  
		{ 
			KillMe(pBus, SYS_ERR_LOGIN); 
			return; 
		}	 
 
		ClearRunFlag(RUNF_NOLOGIN); 
	} 
	else 
	{ 
		tSleep(g_Sys.AddrInfo.wAddr);  //使得各板登录错时 
		Login(pBus, EXTIO_FUN_CONF, 0); 
	} 
} 
 
static void ProcDi(VExtIoSH *pBus, VExtIoFrmHead *pRec) 
{ 
	if (pRec->byFun == EXTIO_FUN_CONF) 
	{ 
		if (pRec->byCnt == pBus->byDiCnt) ClearRunFlag(RUNF_DIF); 
	} 
	else  
		evSend(pBus->Col.nId, EV_UFLAG_DI); 
} 
 
static void ProcTimer(VExtIoFrmHead *pRec) 
{ 
#ifdef INCLUDE_TIMER 
	SetSysClock((void *)(pRec+1), CALCLOCK); 
#endif		 
} 
 
static int ProcCtrlReq(VExtIoSH *pBus, struct VMsgHead *pMsgHead, struct VDBCtrl *pCtrl) 
{ 
#ifdef INCLUDE_YK 
    BYTE value; 
	struct VDBYK *pyk = (struct VDBYK *)pCtrl; 
 
	if  ((pyk->byValue&0x3) == YK_CLOSE)  
		value = 1; 
    else if ((pyk->byValue&0x3) == YK_OPEN )  
		value = 0; 
    else  
		return 4; 
	 
	if (pMsgHead->byMsgID == MI_YKSELECT) 
		return(ykSelect(pyk->wID, value)); 
	else if (pMsgHead->byMsgID == MI_YKOPRATE) 
		return(ykOperate(pyk->wID, value, 0)); 
    else if (pMsgHead->byMsgID == MI_YKCANCEL)		 
		return(ykCancel(pyk->wID, value)); 
#else 
	return 5; 
#endif 
} 
 
static void ProcMsg(VExtIoSH *pBus, VExtIoFrmHead *pRec) 
{ 
    int ret; 
	VPcolCommBuf *Send = &pBus->Col.Send;	 
    struct VMsgHead *pMsgHead = (struct VMsgHead *)(pRec+1); 
	struct VDBCtrl *pCtrl = (struct VDBCtrl *)(pMsgHead+1); 
	 
	ret = 5; 
 
	if (((pMsgHead->byMsgID&MI_MASK) == MI_YK_MASK) || ((pMsgHead->byMsgID&MI_MASK) == MI_YT_MASK)) 
		ret = ProcCtrlReq(pBus, pMsgHead, pCtrl); 
 
	pCtrl->byStatus = (BYTE)ret; 
		 
	SendFrameHead(pBus, EXTIO_TYPE_MSG, EXTIO_FUN_DATA, 0); 
	memcpy(Send->pBuf+Send->wWritePtr, pMsgHead, pMsgHead->wLength);	 
	Send->wWritePtr += pMsgHead->wLength; 
	SendFrameTail(pBus, FRM_PRIO_LEV2); 
} 
 
static void ProcDataRefresh(VExtIoSH *pBus) 
{ 
	evSend(pBus->Col.nId, EV_UFLAG_DI); 
} 
	 
static void ProcFrm(void *arg) 
{ 
	VExtIoSH *pBus = (VExtIoSH *)arg; 
	VExtIoFrmHead *pRec = (VExtIoFrmHead *)pBus->Col.RecFrm.pBuf; 
	 
	pBus->nNoFrm = 0; 
 
	if (pRec->byType == EXTIO_TYPE_LOGIN) 
	{ 
		ProcLogin(pBus, pRec); 
		return; 
	}	 
 
    if (TestRunFlag(RUNF_NOLOGIN)) return; 
 
    switch (pRec->byType) 
    { 
        case EXTIO_TYPE_DI: 
			ProcDi(pBus, pRec); 
			break; 
		case EXTIO_TYPE_TIME: 
			ProcTimer(pRec); 
			break; 
		case EXTIO_TYPE_MSG: 
			ProcMsg(pBus, pRec); 
			break; 
		case EXTIO_TYPE_CMD: 
			//ProcCmd(); 
			break; 
		case EXTIO_TYPE_KILL: 
			KillMe(pBus, SYS_ERR_COMM); 
			break; 
		case EXTIO_TYPE_DATAREFRESH: 
			ProcDataRefresh(pBus); 
			break; 
    }	 
} 
 
static void DoDiUrgency(VExtIoSH *pBus) 
{ 
	if (TestRunFlag(RUNF_CFGSYNC_MASK|RUNF_NOLOGIN)) return; 
 
#ifdef INCLUDE_YX 
	SetRunFlag(RUNF_DIF); 
	SendDi(pBus); 
#endif	 
} 
 
static void DoTimeOut(VExtIoSH *pBus) 
{ 
    static int cnt_1s = 0; 
 
    cnt_1s++; 
	if (cnt_1s == SECTOTICK(1)) 
	{ 
		cnt_1s = 0; 
		if (TestRunFlag(RUNF_NOLOGIN)) 
	    { 
			pBus->nNoFrm = 0; 
			Login(pBus, EXTIO_FUN_DATA, 0|EXTIO_CTRL_MASTER);  
			return; 
		} 
 
		pBus->nNoFrm++; 
		if (pBus->nNoFrm == EXTIO_HBEAT_TM) 
			HBeat(pBus); 
		else if (pBus->nNoFrm >= EXTIO_LOGOUT_TM) 
		{ 
			pBus->nNoFrm = 0; 
			SetRunFlag(RUNF_NOLOGIN); 
			return; 
		}			 
	}	 
 
	pBus->cnt_ms++; 
	if (pBus->cnt_ms == 3) 
	{ 
		pBus->cnt_ms = 0; 
#ifdef INCLUDE_YX 
		if (TestRunFlag(RUNF_DIF)) 
			SendDi(pBus);		 
#endif	 
	} 
} 
 
static void DoHBeat(VExtIoSH *pBus) 
{	 
	pBus->nNoFrm = EXTIO_HBEAT_TM-1; 
} 
 
void extio_high_Init(int tid) 
{ 
    VExtIoSH *pbus; 
 
    tSleep(g_Sys.AddrInfo.wAddr);  //使得各板登录错时 
		 
	pbus = (VExtIoSH *)malloc(sizeof(VExtIoSH)); 
	memset(pbus, 0, sizeof(VExtIoSH)); 
	 
	PcolInit(tid, &pbus->Col, ProcFrm, SearchOneFrame); 
 
    tmEvEvery(tid, 1);	 
	tCreate(tid, (void  *)pbus, (ENTRYPTR)extios_high); 
} 
 
void extios_high(VExtIoSH *pBus) 
{ 
    DWORD events; 
 
    evReceive(pBus->Col.nId, EV_RX_AVAIL|EV_UFLAG_DI|EV_HBEAT|EV_TM1|EV_KILLBUS, &events); 
 
    if (events & EV_UFLAG_DI)         
		DoDiUrgency(pBus); 
		 
	if (events & EV_HBEAT) 
		DoHBeat(pBus); 
 
    if (events & EV_RX_AVAIL)  
		DoReceive(&pBus->Col);	 
 
	if (events & EV_TM1)  
		DoTimeOut(pBus); 
 
	if (events & EV_KILLBUS) 
		KillMe(pBus, SYS_ERR_CFG); 
}