⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serlink.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Serial link communications core.
*
****************************************************************************/


#include "trpimp.h"
#include "trperr.h"
#include "stddef.h"
#include "string.h"
#include "serial.h"
#include "packet.h"

static int BaudCounter;           /* baud rate counter */
static int LastResponse = NAK;    /* last response holder */
static int Errors = 0;            /* Errors so far */
static int PrevErrors = 0;        /* Errors of previous BlockSend() operation */
static unsigned SendBlkNo = 0;    /* next block number to send */
static unsigned ReceiveBlkNo = 0; /* next block number to receive */
static unsigned BytesReceived;    /* # bytes from last receive */

int MaxBaud;

#define BAUD_ENTRY( x ) #x, sizeof( #x ) - 1, TEST_TIME( x )

baud_entry BaudTable[] = {
        BAUD_ENTRY( 115200 ),
        BAUD_ENTRY( 57600 ),
        BAUD_ENTRY( 38400 ),
        BAUD_ENTRY( 19200 ),
        BAUD_ENTRY( 9600 ),
        BAUD_ENTRY( 4800 ),
        BAUD_ENTRY( 2400 ),
        BAUD_ENTRY( 1200 ),
        "0", 1, 0,
};

extern char     *ParsePortSpec( char * * );
extern char     *InitSys( void );
extern void     ResetSys( void );
extern bool     Baud( int );
extern void     ClearCom( void );
extern int      GetByte( void );
extern void     SendByte( int );
extern void     DonePort( void );
extern bool     CheckPendingError( void );
extern void     ClearLastChar( void );
extern void     ZeroWaitCount( void );
extern unsigned WaitCount( void );
extern int      WaitByte( unsigned );
extern void     Wait( unsigned );
extern void     StartBlockTrans( void );
extern void     StopBlockTrans( void );
#ifdef SERVER
extern void     ServMessage( char * );
#endif

void SyncPoint( unsigned tick )
{
    Wait( tick - WaitCount() );
}


static int SenderHandshake( void )
{
    unsigned wait_time;     /* used to test for time-out */
    int      reply;         /* storing data received from other machine */

    wait_time = WaitCount() + SYNC_TIME_OUT;   /* limit for time out */
    if( MaxBaud == MIN_BAUD ) wait_time += SEC(1);
    SendByte( SYNC_BYTE );      /* send SYNC_BYTE */
    for( ;; ) {                 /* loop until ACK received or time out */
        reply = WaitByte( 1 );  /* get reply */
        if( reply == ACK ) break;       /* ACK received; go to next operation */
        if( reply == HI ) {             /* return HI received */
            SendByte( HI );
        } else if( WaitCount() > wait_time ) {    /* time out */
            return( FAIL );
        }                            /* not yet time out; loop */
    }
    SendByte( SYNC_END );
    return( SUCCESS );
}

/* This routine is one side of the set baud rate routine -- sender
   Result:   SUCCESS or FAIL    */


static int SetBaudSender( void )
{
    int     data;           /* storing sync string data to other machine */
    int     i;              /* loop index */
    int     wait_time;

    if( !SenderHandshake() ) return( FAIL );
    /* sync byte received ... send string */
    StartBlockTrans();
    for( i = data = 0; i < SYNC_LEN; i++, data = (data + SYNC_INC) & 0xff ) {
        SendByte( data );            /* send sync string bytes */
    }
    StopBlockTrans();
    wait_time = WaitCount() + SYNC_TIME_OUT;    /* limit for time out */
    /* If MaxBaud == MIN_BAUD, we're talking over a modem and it might
       have buffered characters that haven't been transmitted yet. */
    if( MaxBaud == MIN_BAUD ) wait_time += SEC(2);
    for( ;; ) {
        if( WaitByte( 1 ) == TAK ) {
            SendByte( ACK );
            if( WaitByte( SEC(1)/2 ) == TAK ) {
                return( SUCCESS );
            } else {
                return( FAIL );
            }
        } else if( WaitCount() >= wait_time ) {
              /* break not found; other end have not acknowledged string */
            return( FAIL );
        }
    }
}


/*========================================================================*/
/*========================================================================*/


/* This routine determines if speed sync string received ok.
   Input:    Receive buffer should have sync string
   Return:   SUCCESS or FAIL  */

static int CheckSyncString( void )
{
    int syn_c;         /* correct sync string bytes value */
    int i;             /* loop index */
    unsigned    wait;

    if( CheckPendingError() ) return( FAIL );
    wait = (MaxBaud == MIN_BAUD) ? SEC(2) : (SEC(1)/4);
    for( syn_c = i = 0; i < SYNC_LEN; ++i, syn_c = (syn_c + SYNC_INC) & 0xff ) {
        if( WaitByte( wait ) != syn_c ) {  /* error -- timeout or incorrect data */
            return( FAIL );
        }
        wait = SEC(1)/4;
    }
    return( SUCCESS );
}


/*========================================================================*/
/*========================================================================*/

static int ReceiverHandshake( void )
{
    int reply;         /* storing data received from other machine */
    int wait_time;

    wait_time = WaitCount() + SYNC_TIME_OUT;
    if( MaxBaud == MIN_BAUD ) wait_time += SEC(1);
    for( ;; ) {             /* loop until SYNC_END received or time out */
        reply = WaitByte( 1 );             /* get character */
        if( reply == SYNC_END ) break;     /* SYNC_END received; continue */
        if( reply == SYNC_BYTE ) {         /* SYNC_BYTE received; send ACK */
            SendByte( ACK );
        } else if( reply == HI ) {        /* return HI received */
            SendByte( HI );
        } else if( WaitCount() >= wait_time ) { /* 2 sec time out */
            return( FAIL );
        }                               /* not yet time out; loop */
    }
    return( SUCCESS );
}

/* This routine is one side of the set baud rate routine -- receiver
   Result:   SUCCESS or FAIL    */

static int SetBaudReceiver( void )
{
    unsigned    wait;

    if( !ReceiverHandshake() ) return( FAIL );
    /* sync string should have been received; and in receive buffer now
       CheckSyncString() checks if sync string is received successfully */
    if( CheckSyncString() ) {
        SendByte( TAK );
        wait = (MaxBaud == MIN_BAUD) ? SEC(2) : SEC(1)/2;
        if( WaitByte( wait ) == ACK ) {
            SendByte( TAK );
            return( SUCCESS );
        } else {
            return( FAIL );
        }
    } else {
        return( FAIL );
    }
}


/*========================================================================*/
/*========================================================================*/


/* This routine tries to establish reliable connection at a specific
   baud rate.    baud_index contains the baud rate index
   Output:   SUCCESS or FAIL                           */

static int SetBaud( int baud_index, int *sync_point_p )
{
    int reply;         /* storing data received from other machine */
    int sync_point;

    sync_point = *sync_point_p;
    *sync_point_p += MAX_BAUD_SET_TICKS + 3*SYNC_SLOP;
    if( !Baud( baud_index ) ) return( FAIL );       /* sets up baud rate */
    SyncPoint( sync_point );
    ClearCom();
    Wait( SYNC_SLOP );
    SendByte( HI );
    reply = WaitByte( SYNC_SLOP*2 );
    if( reply != HI ) {
        return( FAIL );
    }
    /* now go the other way */
    *sync_point_p += BaudTable[ baud_index ].full_test_ticks;
#ifdef SERVER
    if( !SetBaudReceiver() ) return( FAIL );
    if( !SetBaudSender() ) return( FAIL );
#else
    if( !SetBaudSender() ) return( FAIL );
    if( !SetBaudReceiver() ) return( FAIL );
#endif
    return( SUCCESS );
}


/*========================================================================*/
/*========================================================================*/


bool MarchToTheSameDrummer( void )
{
    int got;

#ifdef SERVER
    SendByte( LOK );
#else
    if( ( got = WaitByte( SEC( 2 ) ) ) != LOK ) {
        return( FAIL );
    }
#endif
#ifndef SERVER
    SendByte( ACK );
#else
    if( ( got = WaitByte( SEC(1)/2 ) ) != ACK ) {
        return( FAIL );
    }
#endif
    Wait( 1 );  /* don't go till the timer hits exactly on the tick */
    ZeroWaitCount();
    return( SUCCESS );
}


bool SetSyncTime( void )
{
    if( MaxBaud != MIN_BAUD ) {
        if( !Baud( LOW_BAUD ) ) return( FAIL );
    }
#ifdef SERVER
    if( WaitByte( SEC(1)/10 ) != HI ) {
        return( FAIL );
    }
#else
    SendByte( HI );
#endif
    return( MarchToTheSameDrummer() );
}

/*========================================================================*/
/*========================================================================*/


/* This routine sets up the highest possible baud rate.
   BaudCounter contains the baud rate index
   Returns:  SUCCESS or FAIL                                */

static int Speed( void )
{
    int  sync_point;

    if( !MarchToTheSameDrummer() ) return( FAIL );
    sync_point = MAX_BAUD_SET_TICKS;
    for( ;; ) {
        if( SetBaud( BaudCounter, &sync_point ) ) break;
        ++BaudCounter;                /*  ... try next slower speed */
        if( BaudCounter >= MIN_BAUD ) {
            BaudCounter = MIN_BAUD;
            return( FAIL );
        }
    }
    return( SUCCESS );      /* link established */
}


/*========================================================================*/
/*========================================================================*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -