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

📄 sernt.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            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:  Win32 Serial handling routines.
*
****************************************************************************/


#include <windows.h>
#undef NO_DATA      // Clashes with define in serial.h

#include <stdio.h>
#include <stddef.h>
#include "trpimp.h"
#include "trperr.h"
#include "serial.h"

#define BREAK_TIME      4       // In DOS timer ticks, I think (55ms)

int ErrorFlag;
int BreakFlag;
static int currentBaudRateIndex;
static DWORD lastTickReset;

static HANDLE hSerial = INVALID_HANDLE_VALUE;
static int comPortNumber = 1;

//////////////////////////////////////////////////////////////////////////
// Read and write caches to reduce the number of ReadFile and WriteFile
// calls which have to occur.
//
static BYTE writeCache[1024];
static size_t writeCacheLevel;
static bool bBlockWriteMode;

static BYTE readCache[1024];
static size_t readCacheIndex;
static DWORD readCacheLevel;


void Trace(const char* fmt, ...)
{
    va_list         va;
    static char     traceBuffer[1000];

    va_start( va, fmt );

    vsprintf( traceBuffer, fmt, va );
    OutputDebugString( traceBuffer );

    va_end( va );
}

void ZeroWaitCount( void )
{
    lastTickReset = GetTickCount();
}


unsigned WaitCount( void )
{
    return( (GetTickCount() - lastTickReset) / 55 );
}


char *InitSys( void )
{
    DCB             devCon;
    char            deviceFileName[20];
    COMMTIMEOUTS    timeouts = { MAXDWORD, MAXDWORD, 1, 0, 0 };

    sprintf( deviceFileName, "\\\\.\\COM%d", comPortNumber );

    Trace( "InitSys: '%s'\n", deviceFileName );

    currentBaudRateIndex = -1;

    ZeroWaitCount();

    hSerial = CreateFile( deviceFileName,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        0L,
        NULL );

    if( INVALID_HANDLE_VALUE == hSerial ) {
        Trace( "InitSys: CreateFile failed '%s'\n", deviceFileName );
        return NULL;
    }

    // Set up a big RX buffer
    if( !SetupComm( hSerial, 1000, 1000 ) ) {
        // This odd circumstance seems to occur if the port has been assigned to a printer
        Trace( "InitSys: Setupcom failed '%s'\n", deviceFileName );
        CloseHandle( hSerial );
        hSerial = INVALID_HANDLE_VALUE;
        return NULL;
    }

    // Configure the serial port
    GetCommState(hSerial, &devCon);

    devCon.BaudRate = 9600;
    devCon.ByteSize = 8;
    devCon.Parity = NOPARITY;
    devCon.StopBits = ONESTOPBIT;
    devCon.fParity = FALSE;

    devCon.fDsrSensitivity = FALSE;
    devCon.fDtrControl = FALSE;
    devCon.fRtsControl = RTS_CONTROL_DISABLE;
    devCon.fOutxCtsFlow = FALSE;
    devCon.fOutxDsrFlow = FALSE;
    devCon.fInX = FALSE;
    devCon.fOutX = FALSE;
    SetCommState(hSerial, &devCon);

    SetCommTimeouts(hSerial, &timeouts);

    EscapeCommFunction(hSerial, SETDTR);
    EscapeCommFunction(hSerial, SETRTS);

    return( NULL );
}


void ResetSys( void )
{
    if(hSerial != INVALID_HANDLE_VALUE) {
        CloseHandle( hSerial );
        hSerial = INVALID_HANDLE_VALUE;
    }
}

bool Terminate( void )
{
    ResetSys();
    return( TRUE );
}

static void FlushWriteCache( void )
{
    if( writeCacheLevel > 0 ) {
        DWORD nBytesWritten;
        WriteFile( hSerial, writeCache, writeCacheLevel, &nBytesWritten, NULL );
        writeCacheLevel = 0;
    }
}

static void InsertWriteCacheByte( BYTE newByte )
{
    if( writeCacheLevel >= sizeof( writeCache) ) {
        FlushWriteCache();
    }
    writeCache[writeCacheLevel++] = newByte;
}

void SendByte( int value )
{
    InsertWriteCacheByte(value);
    if( !bBlockWriteMode ) {
        FlushWriteCache();
    }

    //  Trace("Ser: Wrote 0x%x\n", outByte);
}

void StartBlockTrans( void )
{
    bBlockWriteMode = TRUE;
}

void StopBlockTrans( void )
{
    bBlockWriteMode = FALSE;
    FlushWriteCache();
}


int GetByte( void )
{
    if( readCacheIndex < readCacheLevel ) {
        return readCache[readCacheIndex++];
    } else {
        // Cache is empty
        readCacheIndex = readCacheLevel = 0;
        if( ReadFile( hSerial, readCache, sizeof( readCache ), &readCacheLevel, NULL ) ) {
            if( readCacheLevel > 0) {
                return readCache[readCacheIndex++];
            }
        }
    }
    return -1;
}


void ClearCom( void )
{
    writeCacheLevel = 0;
}


void SendABreak( void )
{
    EscapeCommFunction( hSerial, SETBREAK );
    Sleep( BREAK_TIME * 55 );
    EscapeCommFunction( hSerial, CLRBREAK );
}

bool TestForBreak( void )
{
    DWORD       errors;
    COMSTAT     comStat;

    if( ClearCommError( hSerial, &errors, &comStat ) ) {
        if( errors & CE_BREAK ) {
            return TRUE;
        }
    }
    return( FALSE );
}


int Divisor[] = { 1, 2, 3, 6, 12, 24, 48, 96, 0 };

bool Baud( int index )
{
    DCB devCon;

    ErrorFlag = 0;
    BreakFlag = 0;
    if( index == MIN_BAUD ) {
        Trace("Ser: Modem flag set\n");
        return( TRUE );
    }

    if( index == currentBaudRateIndex ) return( TRUE );

    GetCommState(hSerial, &devCon);
    devCon.BaudRate = 115200 / Divisor[index];
    Trace("Ser: Baud set: %d\n", devCon.BaudRate);
    SetCommState(hSerial, &devCon);

    currentBaudRateIndex = index;

    return( TRUE );
}

char *ParsePortSpec( char **spec )
{
    comPortNumber = 1;
    if( spec != NULL ) {
        char ch = **spec;

        if( ch >= '1' && ch <= '9' ) {
            comPortNumber = ch - '0';
            ch = *++*spec;
        }
        if( ch != '\0' && ch != '.' )
            return( TRP_ERR_invalid_serial_port_number );
    }
    return( NULL );
}


void DonePort( void )
{
}


bool CheckPendingError( void )
{
    int old_error;

    old_error = ErrorFlag;
    ErrorFlag = 0;
    return( old_error != 0 );
}


void ClearLastChar( void )
{
    // Wait for the output buffer to empty
    FlushWriteCache();
    for( ;; ) {
        DWORD       errors;
        COMSTAT     comStat;

        if( !ClearCommError( hSerial, &errors, &comStat ) ) {
            break;
        }
        if( comStat.cbOutQue == 0 ) {
            break;
        }
        Sleep( 0 );
    }
}

⌨️ 快捷键说明

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