📄 rs232.cpp
字号:
// *********************** START OF RS232.CPP ***********************
//
//
//
// This C++ file contains the definitions for all functions defined for
// the base class. Most of these are dummy functions that do nothing but
// return a warning message to the calling routine. A well defined derived
// class will usually define new versions of these virtual functions,
// which means they will never be called.
//
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "rs232.h"
// FlushRXBuffer() doesn't have to be defined for every
// derived class. This default function should be able to flush
// the buffer using the mandatory read_buffer() function.
// Classes such as PC8250 that have direct access to their
// receive buffer can implement more efficient versions than this
// if they want.
int RS232::FlushRXBuffer( void )
{
char buf[ 32 ];
for ( ; ; ) {
if ( error_status != RS232_SUCCESS )
return error_status;
read_buffer( buf, 32 );
if ( ByteCount == 0 )
break;
}
return RS232_SUCCESS;
}
// Peek( void ) isn't a virtual function. This is one of the
// few normal member functions in class RS232. It peeks at a
// single byte using the Peek( char *, int ) function.
int RS232::Peek( void )
{
char c;
int status;
if ( error_status < RS232_SUCCESS )
return error_status;
if ( ( status = Peek( &c, 1 ) ) < RS232_SUCCESS )
return status;
if ( ByteCount < 1 )
return RS232_TIMEOUT;
return (int) c;
}
//
// This member function returns the character translation for one
// of the error codes defined in the base class. It is called by
// the ErrorName() function for a derived class after checking to
// see if the error code is not a new one defined by the derived
// class.
char * RS232::ErrorName( int error )
{
switch ( error ) {
case RS232_SUCCESS :
return( "Success" );
case RS232_WARNING :
return( "General Warning" );
case RS232_FUNCTION_NOT_SUPPORTED :
return( "Function not supported" );
case RS232_TIMEOUT :
return( "Timeout" );
case RS232_ILLEGAL_BAUD_RATE :
return( "Illegal baud rate" );
case RS232_ILLEGAL_PARITY_SETTING :
return( "Illegal parity setting" );
case RS232_ILLEGAL_WORD_LENGTH :
return( "Illegal word length" );
case RS232_ILLEGAL_STOP_BITS :
return( "Illegal stop bits" );
case RS232_ILLEGAL_LINE_NUMBER :
return( "Illegal line number" );
case RS232_NO_TERMINATOR :
return( "No terminator" );
case RS232_NO_MODEM_RESPONSE :
return( "No modem response" );
case RS232_DTR_NOT_SUPPORTED :
return( "DTR control not supported" );
case RS232_RTS_NOT_SUPPORTED :
return( "RTS control not supported" );
case RS232_RTS_CTS_NOT_SUPPORTED :
return( "RTS/CTS handshaking not supported" );
case RS232_DTR_DSR_NOT_SUPPORTED :
return( "DTR/DSR handshaking not supported" );
case RS232_XON_XOFF_NOT_SUPPORTED :
return( "XON/XOFF handshaking not supported" );
case RS232_ERROR :
return( "General Error" );
case RS232_IRQ_IN_USE :
return( "IRQ line in use" );
case RS232_PORT_NOT_FOUND :
return( "Port not found" );
case RS232_PORT_IN_USE :
return( "Port in use" );
case RS232_ILLEGAL_IRQ :
return( "Illegal IRQ" );
case RS232_MEMORY_ALLOCATION_ERROR :
return( "Memory allocation error" );
default :
return( "???" );
}
}
//
// The base class contributes four lines of output to the Debug
// output. Note that it returns the number 4 if called with a
// null buffer, to pass this information on. The four lines of
// output contain everything the base class knows about the port,
// which are its current settings, saved settings, port name, and
// error status. For line numbers greater than three, the derived
// class provides additional lines of debug output. Note that
// this function is called by the version of FormatDebugOutput()
// defined for the derived class.
int RS232::FormatDebugOutput( char *buffer, int line_number )
{
if ( buffer == 0 )
return 4;
switch( line_number ) {
case 0 :
sprintf( buffer, "Base class: RS232 "
"COM%-2d "
"Status: %-35.35s",
port_name + 1,
ErrorName( error_status ) );
return RS232_SUCCESS;
case 1 :
sprintf( buffer, "Byte count: %5u "
"Elapsed time: %9ld "
"TX Free: %5u "
"RX Used: %5u",
ByteCount,
ElapsedTime,
TXSpaceFree(),
RXSpaceUsed() );
return RS232_SUCCESS;
case 2 :
sprintf( buffer,
"Saved port: %6ld,%c,%2d,%2d "
"DTR,RTS: %2d,%2d "
"XON/OFF,RTS/CTS,DTR/DSR: %2d,%2d,%2d",
saved_settings.BaudRate,
saved_settings.Parity,
saved_settings.WordLength,
saved_settings.StopBits,
saved_settings.Dtr,
saved_settings.Rts,
saved_settings.XonXoff,
saved_settings.RtsCts,
saved_settings.DtrDsr );
return RS232_SUCCESS;
case 3 :
sprintf( buffer,
"Current port: %6ld,%c,%1d,%1d "
"DTR,RTS: %2d,%2d "
"XON/OFF,RTS/CTS,DTR/DSR: %2d,%2d,%2d",
settings.BaudRate,
settings.Parity,
settings.WordLength,
settings.StopBits,
settings.Dtr,
settings.Rts,
settings.XonXoff,
settings.RtsCts,
settings.DtrDsr );
return RS232_SUCCESS;
default :
return RS232_ILLEGAL_LINE_NUMBER;
}
}
// This non-virtual member function operates by repeatedly
// calling the read_byte() function for the derived class. It
// handles the optional milliseconds parameter, which determines
// how long the function will wait for input before returning a
// timeout. The idle function is called while waiting.
int RS232::Read( long milliseconds )
{
int c;
long start_time;
int idle_status = RS232_SUCCESS;
ElapsedTime = 0;
ByteCount = 0;
if ( error_status < RS232_SUCCESS )
return error_status;
start_time = ReadTime();
for ( ; ; ) {
c = read_byte();
if ( c >= 0 )
break;
if ( milliseconds != FOREVER &&
( ReadTime() - start_time ) >= milliseconds )
break;
if ( ( idle_status = IdleFunction() ) < RS232_SUCCESS )
break;
}
ElapsedTime = ReadTime() - start_time;
if ( idle_status < RS232_SUCCESS )
return idle_status;
if ( c >= 0 ) {
ByteCount = 1;
return c;
}
return RS232_TIMEOUT;
}
// This non-virtual member function of class RS232 operates by
// repeatedly calling the virtual function write_byte() for the
// derived class. The milliseconds parameter defines how long
// the function will keep trying before giving up. While
// waiting, the idle function is called.
int RS232::Write( int c, long milliseconds )
{
int write_status;
int idle_status = RS232_SUCCESS;
long start_time;
ElapsedTime = 0;
ByteCount = 0;
if ( error_status < 0 )
return error_status;
start_time = ReadTime();
for ( ; ; ) {
write_status = write_byte( c );
if ( write_status != RS232_TIMEOUT )
break;
if ( milliseconds != FOREVER &&
( ReadTime() - start_time ) >= milliseconds )
break;
if ( ( idle_status = IdleFunction() ) < RS232_SUCCESS )
break;
}
ElapsedTime = ReadTime() - start_time;
if ( idle_status < RS232_SUCCESS )
return idle_status;
if ( write_status < RS232_SUCCESS )
return write_status;
ByteCount = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -