📄 serqnx.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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stddef.h>
#include <i86.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/osinfo.h>
#include <sys/dev.h>
#include <sys/kernel.h>
#include "serial.h"
#include "trpimp.h"
#include "trperr.h"
int CurrentBaud;
unsigned long MSecsAtZero;
unsigned long StartSecs;
struct _timesel __far *SysTime;
int ComPort = 0;
struct termios SavePort;
struct termios CurrPort;
bool HadError;
char BlockBuff[300];
int BlockIndex;
unsigned long NSecScale;
extern int MaxBaud;
#define MILLISEC_PER_TICK 55
#define GET_MSECS (SysTime->nsec / NSecScale + (SysTime->seconds-StartSecs) * 1000)
void ZeroWaitCount()
{
MSecsAtZero = GET_MSECS;
}
unsigned WaitCount()
{
return( ( GET_MSECS - MSecsAtZero ) / MILLISEC_PER_TICK );
}
void ClearCom()
{
tcflush( ComPort, TCIOFLUSH );
}
void SendByte( int value )
{
if( BlockIndex >= 0 ) {
BlockBuff[BlockIndex++] = value;
} else {
write( ComPort, &value, 1 );
tcdrain( ComPort );
}
}
void StartBlockTrans()
{
BlockIndex = 0;
}
void StopBlockTrans()
{
if( BlockIndex > 0 ) {
write( ComPort, BlockBuff, BlockIndex );
tcdrain( ComPort );
}
BlockIndex = -1;
}
int WaitByte( unsigned ticks )
{
unsigned char data;
unsigned timeout;
timeout = (ticks * MILLISEC_PER_TICK) / 100;
if( ticks > 0 && timeout == 0 ) timeout = 1;
if( dev_read( ComPort, &data, 1, 0, timeout, 0, 0, 0 ) != 1 ) {
return( NO_DATA );
}
if( data == 0xff ) {
dev_read( ComPort, &data, 1, 0, timeout, 0, 0, 0 );
if( data == 0xff ) return( data );
/* a transmission error has occured */
HadError = TRUE;
dev_read( ComPort, &data, 1, 0, timeout, 0, 0, 0 );
return( NO_DATA );
}
return( data );
}
int GetByte()
{
return( WaitByte( 0 ) );
}
speed_t Rate[] = {
B115200,
B57600,
B38400,
B19200,
B9600,
B4800,
B2400,
B1200,
B0 };
bool Baud( int index )
{
speed_t temp;
if( index == MIN_BAUD ) return( TRUE );
if( index == CurrentBaud ) return( TRUE );
temp = Rate[index];
if( temp == B0 ) return( FALSE );
cfsetispeed( &CurrPort, temp );
cfsetospeed( &CurrPort, temp );
if( tcsetattr( ComPort, TCSADRAIN, &CurrPort ) != 0 ) {
return( FALSE );
}
CurrentBaud = index;
return( TRUE );
}
char *ParsePortSpec( char * *spec )
{
int port;
int nid;
char ch;
char *parm;
char *start;
static char name[] = "//___/dev/ser__";
parm = (spec == NULL) ? "" : *spec;
nid = 0;
port = 0;
if( *parm == '/' ) {
start = parm;
do {
ch = *++parm;
} while( ch != '.' && ch != '\0' );
*parm = '\0';
if( ComPort != 0 ) {
DonePort();
}
ComPort = open( start, O_RDWR );
*parm = ch;
if( spec != NULL ) *spec = parm;
} else {
for( ;; ) {
ch = *parm;
if( ch < '0' || ch > '9' ) break;
port = port * 10 + (ch-'0');
++parm;
}
if( ch == ',' ) {
nid = port;
if( nid > 255 ) return( TRP_QNX_invalid_node_number );
port = 0;
for( ;; ) {
++parm;
ch = *parm;
if( ch < '0' || ch > '9' ) break;
port = port * 10 + (ch-'0');
}
}
if( port == 0 ) port = 1;
if( port > 99 ) return( TRP_ERR_invalid_serial_port_number );
if( spec != NULL ) *spec = parm;
name[4] = nid % 10 + '0';
nid /= 10;
name[3] = nid % 10 + '0';
nid /= 10;
name[2] = nid % 10 + '0';
name[ sizeof( name ) - 3 ] = port / 10 + '0';
name[ sizeof( name ) - 2 ] = port % 10 + '0';
if( ComPort != 0 ) {
DonePort();
}
ComPort = open( name, O_RDWR );
}
if( ComPort < 0 ) {
ComPort = 0;
return( (errno == ENOENT) ?
TRP_ERR_serial_port_does_not_exist : TRP_ERR_serial_port_not_available );
}
tcgetattr( ComPort, &SavePort );
CurrPort = SavePort;
CurrPort.c_iflag = PARMRK;
CurrPort.c_oflag = 0;
CurrPort.c_cflag = CREAD | CS8;
CurrPort.c_lflag = 0;
if( tcsetattr( ComPort, TCSADRAIN, &CurrPort ) != 0 ) {
return( TRP_ERR_could_not_set_serial_port_characteristics );
}
return( NULL );
}
void DonePort()
{
if( ComPort != 0 ) {
tcsetattr( ComPort, TCSADRAIN, &SavePort );
close( ComPort );
ComPort = 0;
}
}
bool CheckPendingError()
{
bool ret;
ret = HadError;
HadError = FALSE;
return( ret );
}
void ClearLastChar()
{
}
void Wait( int timer_ticks )
{
unsigned wait_time;
if( timer_ticks < 0 ) return;
wait_time = WaitCount() + timer_ticks;
while( WaitCount() < wait_time ) Yield();
}
char *InitSys( void )
{
struct _osinfo osinfo;
qnx_osinfo( 0, &osinfo );
SysTime = MK_FP( osinfo.timesel, 0 );
NSecScale = (osinfo.version >= 410) ? 1000000 : (64UL*1024)*10;
StartSecs = SysTime->seconds;
CurrentBaud = -1;
BlockIndex = -1;
return( NULL );
}
void ResetSys( void )
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -