/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/FWSETUP/SERIALCM.CPP   1.7   17 Apr 1997 16:38:20   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/FWSETUP/SERIALCM.CPP  $
** 
**    Rev 1.7   17 Apr 1997 16:38:20   ZJRD
** No change.
** 
**    Rev 1.6   16 Apr 1997 11:18:16   ZJRD
** No change.
** 
**    Rev 1.5   10 Apr 1997 15:59:12   ZJRD
** 2.09F
** 
**    Rev 1.3   03 Apr 1997 15:37:18   ZJRD
** No change.
** 
**    Rev 1.2   27 Mar 1997 15:21:58   ZJRD
** No change.
** 
**    Rev 1.1   19 Mar 1997 11:50:00   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 15:02:24   ZJRD
** Initial revision.
** 
**    Rev 1.6   21 Oct 1996 09:19:20   ZJRD
** No change.
** 
**    Rev 1.5   09 Oct 1996 13:51:44   ZJRD
** No change.
** 
**    Rev 1.4   23 Sep 1996 10:38:46   ZJRD
** No change.
** 
**    Rev 1.3   06 Sep 1996 13:53:08   ZJRD
** No change.
** 
**    Rev 1.2   02 Sep 1996 11:34:22   ZJRD
** PIC-SLD Version 0.50
** 
**    Rev 1.0   13 Aug 1996 09:20:06   ZJRD
** Initial revision.
** 
****************************************************************************/

/***************************************************************************
**
** File name : SERIALCM.CPP 
** Author:john chow
** Description:
**    Descript the base function of serial communication for PIC
**
**    Finished date: 96.7
**    modifed date:
**
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/

#include "stdafx.h"

#include "serialcm.h"
//implemention of CBaseCom
void CBaseCom :: SetTimer(unsigned long lTimer)
{ 
    m_lTimer = lTimer;
    _ftime( &m_startTime ); 
 }
void CBaseCom :: RestartTimer()
{ 
    _ftime( &m_startTime ); 
 }
               
               
BOOL CBaseCom::IsTimeOut()
{ 
    _ftime(&m_currentTime);
    unsigned long lTmp1,lTmp2;
    lTmp1 = m_currentTime.time*1000 + m_currentTime.millitm;
    lTmp2 = m_startTime.time*1000 + m_startTime.millitm;
    unsigned long lResult = lTmp1 - lTmp2;
    if(lResult > m_lTimer) 
        return TRUE; else return FALSE;
 }                     
 
BOOL CBaseCom::SendString(BYTE *pBuff,int nLen) 
{       
    if(!m_isCanBeUsed) {
        m_nError = ERR_NOT_REPARE;
        return FALSE;
    }   
    for (int i=0;i<nLen;i++) {
       if (SendByte(pBuff[i])!=TRUE) return FALSE;
       RestartTimer();
    }          
    m_nError = m_nDetailError = ERR_NO;
    return TRUE;        
 }            
 
BOOL CBaseCom::ReceiveString(BYTE *pBuff,int nLen)
{                         
    if(!m_isCanBeUsed) {
        m_nError = ERR_NOT_REPARE;
        return FALSE;
    }   
    for (int i=0;i<nLen;i++) {
       if (ReceiveByte(pBuff[i])!=TRUE) return FALSE;
       RestartTimer();
    }                                  
    m_nError = m_nDetailError = ERR_NO;
    return TRUE;            
 } 
 
//implement of CBaseAgree
CBaseAgree::CBaseAgree()
{ 
    m_strInput = new BYTE[INPUTLEN]; 
    m_strOutput = new BYTE[OUTPUTLEN];                      
    m_nInputStrLen = m_nOutputStrLen = 0;
    if(NULL == m_strInput || NULL == m_strOutput) ASSERT(0);
        
 } 
 
CBaseAgree::~CBaseAgree()
{ 
    if (NULL != m_strInput) delete m_strInput; 
    if (NULL != m_strOutput) delete m_strOutput; 
        
 }  
 
void CBaseAgree::SetOutputStr(BYTE* strOutput,int nLen)
{                                                      
    for (int i = 0; i<nLen; i++) 
        m_strOutput[i] = strOutput[i];
    m_nOutputStrLen = nLen; 
    
 }
 
void CBaseAgree::GetInputStr(BYTE* strInput,int& nLen)
{                                                      
    for (unsigned int i = 0; i<m_nInputStrLen; i++) 
        strInput[i] = m_strInput[i];
    nLen = m_nInputStrLen;  
    
 } 
 
//implement of CPICAgree
BOOL CPICAgree::Init() 
{   
    char strTmp[10];                 
    for (int i =0;i<8;i++) {
        SetTimer(100);    
        FlushBufferIn();
        FlushBufferOut();
        if (FALSE == SendString((unsigned char*)"EPSLD",5)) continue;
        SetTimer(100);
        if(TRUE == ReceiveString((BYTE*)strTmp,5)) {
            strTmp[5] = 0;
            if(0 == strcmp(strTmp,"EPSLD")) {  
                isConnected = TRUE;              
                m_nError = m_nDetailError = ERR_NO;
                return TRUE;
            }
        }       
        if( ERR_ESC == m_nError) break;
    }       
    
    isConnected = FALSE;    
    return FALSE;           
        
 }               
                                         
BOOL CPICAgree::Shakehand(BYTE bTimers)              
{                                        
    if (!isConnected) {
        m_nError = ERR_NOT_CONNECTED;
        return FALSE;
    }
      
    //CLEAR BUFFER
    FlushBufferIn();
    FlushBufferOut();  
      
    BYTE bTmp;
    for (int i=0; i<bTimers; i++) {
        SetTimer(100);
        if(FALSE == SendByte('?')) continue;
        SetTimer(300);
        if(!ReceiveByte(bTmp)) continue;
        else {
            if ('!' == bTmp) {
                m_nError = m_nDetailError = ERR_NO;
                return TRUE;                       
            }    
            m_nError = ERR_RECEIVE_WRONGCODE;   
            return FALSE;
        }    
    }       
                                
    return FALSE;
        
 }
 
BOOL CPICAgree::Shakehand_()
{       

    if (!isConnected) {
        m_nError = ERR_NOT_CONNECTED;
        return FALSE;
    }   
                  
    BYTE bTmp;
    
    SetTimer(nBackTime);
    if((FALSE == ReceiveByte(bTmp)) || '?' != bTmp )
        return FALSE;               
    SetTimer(100);
    if (FALSE == SendByte('!')) return FALSE;
    
    for (int i=0; i<10; i++) {
        SetTimer(100);  
        if (FALSE == ReceiveByte(bTmp)) continue;
        if (':' == bTmp) {
            m_nError = m_nDetailError = ERR_NO;
            return TRUE;                        
        }    
        if ('?' == bTmp) 
            if (FALSE == SendByte('!')) return FALSE;
    }   
                                
    return FALSE; 
        
 }  
 
BOOL CPICAgree::SendHead()  
{       
    if (!isConnected) {
        m_nError = ERR_NOT_CONNECTED;
        return FALSE;
    }   
    
    BYTE strTmp[10];
    while (TRUE) {
        strTmp[0] = ':';
        strTmp[1] = ((m_nOutputStrLen+1)<<8)>>8;
        strTmp[2] = (m_nOutputStrLen+1)>>8;
        strTmp[3] = ~(strTmp[1]+strTmp[2])+1;
    
        SetTimer(100);
        if (FALSE == SendString(strTmp,4)) return FALSE;
        SetTimer(1000);
        if (FALSE == ReceiveByte(strTmp[0])) return FALSE;
        
        /*while ('!' == strTmp[0]) {
			SetTimer(1000);
        	if (FALSE == ReceiveByte(strTmp[0])) return FALSE;        	
        }*/	
        
        if (HEAD_OK == strTmp[0]) {
            m_nError = m_nDetailError = ERR_NO;
            return TRUE;                       
        }    
        if (HEAD_FAIL == strTmp[0]) {
            m_nErrorTime++;
            continue;
        }   
        if ('$' == strTmp[0]) {
            m_nError = ERR_RECEIVE_DOLLAR;
            m_nErrorTime++;
            return FALSE;
        }   
        m_nError = ERR_RECEIVE_WRONGCODE;
        m_nErrorTime++;
        return FALSE;
    }   
    
    
 } 
 
BOOL CPICAgree::SendRec()  
{       
    if (!isConnected) {
        m_nError = ERR_NOT_CONNECTED;
        return FALSE;
    }   
    
    BYTE strTmp[10];
    while (TRUE) {
        m_strOutput[m_nOutputStrLen] = 0;
        for(unsigned int i=0;i<m_nOutputStrLen;i++)
            m_strOutput[m_nOutputStrLen] += m_strOutput[i];
        m_strOutput[m_nOutputStrLen] = ~(m_strOutput[m_nOutputStrLen])+1;   
        SetTimer(100);
        if (FALSE == SendByte(':')) return FALSE;
        
        SetTimer(1000);
        if (FALSE == SendString(m_strOutput,m_nOutputStrLen+1)) return FALSE;
        SetTimer(1000);
        if (FALSE == ReceiveByte(strTmp[0])) return FALSE;
        if (REC_OK == strTmp[0]) {
            m_nError = m_nDetailError = ERR_NO;
            return TRUE;                       
        }    
        if (REC_FAIL == strTmp[0]) {
            m_nErrorTime++;
            continue;
        }   
        if ('$' == strTmp[0]) {
            m_nError = ERR_RECEIVE_DOLLAR;
            m_nErrorTime++;
            return FALSE;
        }                  
        
        m_nError = ERR_RECEIVE_WRONGCODE;
        m_nErrorTime++;
        return FALSE;
    }
    
 }
 
BOOL CPICAgree::ReceiveHead()  
{       
    if (!isConnected) {
        m_nError = ERR_NOT_CONNECTED;
        return FALSE;
    }   
    
    BYTE strTmp[10];
    while (TRUE) {
        SetTimer(1000);
        if (FALSE == ReceiveString(strTmp,3)) 
            if (ERR_TIME_OUT == m_nError) {
                m_nErrorTime++;
                if(FALSE == SendByte('$')) return FALSE;
                m_nError == ERR_SEND_DOLLAR;
                return FALSE;
            } else return FALSE;
                      
        if(0 == (BYTE)(strTmp[0] + strTmp[1] + strTmp[2]) ) {
            m_nInputStrLen = 256*strTmp[1] + strTmp[0];
            SetTimer(100);
            return SendByte(HEAD_OK);
        }   
                      
        m_nErrorTime++;           
        SetTimer(100);
        if (FALSE == SendByte(HEAD_FAIL)) return FALSE;
        SetTimer(1000);
        if (FALSE == ReceiveByte(strTmp[0])) return FALSE;
        if (':' == strTmp[0]) continue;
        
        m_nErrorTime++;
        m_nError = ERR_RECEIVE_WRONGCODE;
        return FALSE;                    
    }   
    
    return FALSE;
    
 } 


BOOL CPICAgree::ReceiveRec()  
{       
    if (!isConnected) {
        m_nError = ERR_NOT_CONNECTED;
        return FALSE;
    }   
    
    BYTE strTmp[10];
    while (TRUE) {
        SetTimer(1000);                                    
        if (FALSE == ReceiveByte(strTmp[0])) return FALSE;
        if (':' != strTmp[0]) {
            m_nError = ERR_RECEIVE_WRONGCODE;
            m_nErrorTime++;
            return FALSE;                    
        }   
        
        SetTimer(1000);
        if (FALSE == ReceiveString(m_strInput,m_nInputStrLen)) 
            if (ERR_TIME_OUT == m_nError) {
                m_nErrorTime++;
                if(FALSE == SendByte('$')) return FALSE;
                m_nError == ERR_SEND_DOLLAR;
                return FALSE;
            } else return FALSE;
                                        
        strTmp[0] = 0;                                
        for (unsigned int i=0;i<m_nInputStrLen;i++) 
            strTmp[0] += m_strInput[i];
        if(0 == strTmp[0]) {
            m_nInputStrLen--;
            SetTimer(100);
            return SendByte(REC_OK);
        }   
                
        SetTimer(100);
        m_nErrorTime++;
        if (FALSE == SendByte(REC_FAIL)) return FALSE;
    }   
    
    
 } 

BOOL CPICAgree::Do() 
{       
while (TRUE) {
    do {
        if(Shakehand()) break;
        if(ERR_TIME_OUT != m_nError)
        	return FALSE;
        if(!IsRelink()) {
            m_nError = ERR_RELINKQUIT;
            m_nDetailError = ERR_SHAKE_HAND;
            return FALSE;
        } else break;   
    } while (TRUE);  
    
    if(ERR_TIME_OUT == m_nError) continue;
    
    do {         
        if(SendHead()) break;
        if(ERR_RECEIVE_DOLLAR == m_nError) break;
        if(ERR_TIME_OUT != m_nError) 
        	return FALSE;
        if(!IsRelink()) {
            m_nError = ERR_RELINKQUIT;
            m_nDetailError = ERR_SEND_HEAD;
            return FALSE;
        } else break;   
    } while (TRUE);
    
    if(ERR_TIME_OUT == m_nError || ERR_RECEIVE_DOLLAR == m_nError) continue;
    
    do {         
        if(SendRec()) break;
        if(ERR_RECEIVE_DOLLAR == m_nError) break;
        if(ERR_TIME_OUT != m_nError) 
        	return FALSE;
        if(!IsRelink()) {
            m_nError = ERR_RELINKQUIT;     
            m_nDetailError = ERR_SEND_REC;
            return FALSE;
        } else break;   
    } while (TRUE);
    
    if(ERR_TIME_OUT == m_nError || ERR_RECEIVE_DOLLAR == m_nError) continue;
    
    do {         
        if(Shakehand_()) break;
        if(ERR_TIME_OUT != m_nError) 
        	return FALSE;
        if(!IsRelink()) {
            m_nError = ERR_RELINKQUIT;    
            m_nDetailError = ERR_SHAKE_HAND_;
            return FALSE;
        } else break;   
    } while (TRUE);         
    
    if(ERR_TIME_OUT == m_nError) continue;
                     
    do {         
        if(ReceiveHead()) break;
        if(ERR_SEND_DOLLAR == m_nError) break;
        if(ERR_TIME_OUT != m_nError) 
        	return FALSE;
        if(!IsRelink()) {
            m_nError = ERR_RELINKQUIT;  
            m_nDetailError = ERR_RECEIVE_HEAD;
            return FALSE;
        } else break;   
    } while (TRUE);
                     
    if(ERR_TIME_OUT == m_nError || ERR_SEND_DOLLAR == m_nError) continue;   
    
    do {         
        if(ReceiveRec()) break;
        if(ERR_SEND_DOLLAR == m_nError) break;
        if(ERR_TIME_OUT != m_nError) 
        	return FALSE;
        if(!IsRelink()) {
            m_nError = ERR_RELINKQUIT;        
            m_nDetailError = ERR_RECEIVE_REC;
            return FALSE;
        } else break;   
    } while (TRUE);
                     
    if(ERR_TIME_OUT == m_nError || ERR_SEND_DOLLAR == m_nError) continue;   
    return TRUE;
}   
}                     
 
//implemention of CBaseSerialPICAgree
BYTE CBaseSerialPICAgree::GetSerialBaudRate()
{   
    return m_bBaudRate;            
 }
 
BYTE CBaseSerialPICAgree::GetSerialPortNum()
{                                        
    return m_bPortNum;
 } 
 
BYTE CBaseSerialPICAgree::GetPICClockType()
{ 
    return m_bPICClockType;
 }

BYTE CBaseSerialPICAgree::GetPICCpuType()
{ 
    return m_bPICCpuType;
 }
 