📄 udoslnk.c
字号:
//---------Copyright (C) 1997 Dallas Semiconductor Corporation--------------
//
// COMUT.C - This source file contains the COM specific utility funcs
// for 16 bit COM communication.
//
// Compiler: VC
// Version:
//
// includes
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "dos.h"
#include "ownet.h"
#include "ds2480.h"
// local function prototypes
SMALLINT OpenCOM(int, char *);
SMALLINT SetupCOM(int, ulong);
void FlushCOM(int);
void CloseCOM(int);
int WriteCOM(int, int, uchar *);
int ReadCOM(int, int, uchar *);
void BreakCOM(int);
void SetBaudCOM(int, uchar);
void PowerCOM(int, short);
//IBAPI RTSCOM(short, short);
//void StdFunc WaitWriteCOM(short);
void MarkTime(void);
SMALLINT ElapsedTime(long);
//IBAPI DSRHigh(short);
void msDelay(int);
void Sleep(long);
long msGettick(void);
// serial interrupt service routines
void __interrupt __far com_serial_int4(ushort,ushort,ushort,ushort,ushort,ushort,ushort,ushort,ushort,
ushort,ushort,ushort,ushort);
void __interrupt __far com_serial_int3(ushort,ushort,ushort,ushort,ushort,ushort,ushort,ushort,ushort,
ushort,ushort,ushort,ushort);
// globals to be used in communication routines
#define INBUF_MASK 63 // mask to and with current pointer
#define INBUFSIZ 64 // number of chars in buffer, 64
// defines to make Microsoft C compatible
#define inportb inp
#define outportb outp
static ulong TimeStamp;
static ulong BigTimeStamp;
static ulong MilliSec=2386;
static HANDLE ComID[MAX_PORTNUM];
static SMALLINT PortState_init = FALSE;
// structure to reference 8250 registers
typedef struct
{
union
{
int com_regs[7];
struct
{
union
{
ushort lsb; // least significant byte of divisor
ushort rbr; // receive buffer register
ushort tbr; // transmit buffer register
} a;
union
{
ushort msb; // most significant byte of divisor
ushort ier; // interrupt enable register
} b;
ushort iir; // interrupt id register
ushort lcr; // line control register
ushort mcr; // modem control register
ushort lsr; // line status register
ushort msr; // modem status register
} nam;
};
} comtype;
// structure to hold the state of the port
typedef struct
{
ushort com_vec_n; // vector number com jumps through
ushort m8259_mask; // 8259 interrupt request mask
ushort port_adr; // address of port. 3f8 or 2f8
uchar inbuf[INBUFSIZ]; // input buffer
ushort inbuf_n; // number of chars in buffer
ushort inbuf_get; // point to beginning of buffer
ushort inbuf_put; // next incoming char goes here
void (_interrupt _far *save_vec)();
comtype com;
} PortStateType;
volatile PortStateType PortState[16];
// last port written/read from
volatile short LastPrt=0;
//---------------------------------------------------------------------------
// Attempt to open a com port. Keep the handle in ComID.
// Set the starting baud rate to 9600.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will
// be used to indicate the port number desired when calling
// all other functions in this library.
//
//
// Returns: the port number if it was succesful otherwise -1
//
int OpenCOMEx(char *port_zstr)
{
int portnum;
if(!PortState_init)
{
int i;
for(i=0; i<MAX_PORTNUM; i++)
PortState[i].port_adr = 0;
PortState_init = TRUE;
}
// check to find first available handle slot
for(portnum = 0; portnum<MAX_PORTNUM; portnum++)
{
if(!ComID[portnum])
break;
}
OWASSERT( portnum<MAX_PORTNUM, OWERROR_PORTNUM_ERROR, -1 );
if(!OpenCOM(portnum, port_zstr))
{
return -1;
}
return portnum;
}
//---------------------------------------------------------------
// Description:
// Attept to open a com port.
// portnum - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
// port_zstr - the string of the port to be used
//
// Returns FALSE if unsuccessful and TRUE if successful.
//
SMALLINT OpenCOM(int portnum, char *port_zstr)
{
ushort i,port_val;
ushort far *ptr = (ushort far *) 0x00400000;
ushort Prt = atoi(&port_zstr[3]);
uchar buff[5];
if(!PortState_init)
{
for(i=0; i<MAX_PORTNUM; i++)
PortState[i].port_adr = 0;
PortState_init = 1;
}
OWASSERT( portnum<MAX_PORTNUM && portnum>=0 && !PortState[portnum].port_adr,
OWERROR_PORTNUM_ERROR, FALSE );
// reset the state of this port
PortState[portnum].port_adr = 0;
PortState[portnum].inbuf_n = 0;
PortState[portnum].inbuf_get = 0;
PortState[portnum].inbuf_put = 0;
// check if already setup
if (PortState[portnum].port_adr != 0)
return SetupCOM(portnum,9600);
port_val = *(ptr + Prt - 1); // get the port base
if (port_val == 0x3f8 || port_val == 0x3e8) // COM1 or COM3
{
PortState[portnum].com_vec_n = 0x0c; // jump thru vectory C
PortState[portnum].m8259_mask = 0x0ef; // mask bit 4
}
else if (port_val == 0x2f8 || port_val == 0x2e8) // COM2 or COM4
{
PortState[portnum].com_vec_n = 0x0b; // jump thru vectory B
PortState[portnum].m8259_mask = 0x0f7; // mask bit 3
}
else // must have found a non standard base
return FALSE;
PortState[portnum].port_adr = port_val; // global assignments
for (i = 0; i < 7; ++i) // set the port values of the registers
PortState[portnum].com.com_regs[i] = PortState[portnum].port_adr + i;
PortState[portnum].save_vec = _dos_getvect(PortState[portnum].com_vec_n); // save the current ISR vector
// setup ISR depending on interrupt
if (PortState[portnum].com_vec_n == 0x0c)
{
printf("setting up com1 interupt.\n");
_dos_setvect(PortState[portnum].com_vec_n, com_serial_int4);
}
else
_dos_setvect(PortState[portnum].com_vec_n, com_serial_int3);
_disable(); // disable interrupts while setting up ISR
// clear dlab in LCR
i = inportb(PortState[portnum].com.nam.lcr);
outportb(PortState[portnum].com.nam.lcr,(uchar)(0x7F & i));
// set rts and dtr in MCR
outportb(PortState[portnum].com.nam.mcr,0x0B);
// interrupt on received data available in IER
outportb(PortState[portnum].com.nam.b.ier,0x01);
// clear bit (3 or 4) so it interrupts unmasked
i = inportb(0x21);
outportb(0x21,(uchar)(PortState[portnum].m8259_mask & i));
// read in what is there
i = inportb(PortState[portnum].com.nam.a.rbr);
// set the baudrate
SetupCOM(portnum,9600);
// clear the interrupt
inportb(PortState[LastPrt].com.nam.iir);
// reset the buffer counters
PortState[portnum].inbuf_n = 0;
PortState[portnum].inbuf_get = 0;
PortState[portnum].inbuf_put = 0;
LastPrt = portnum;
_enable(); // re-enble interrupts
// make sure the device is powered
outportb(PortState[portnum].com.nam.mcr,0x0B);
// reset byte operation
FlushCOM(portnum);
buff[0] = (uchar) (CMD_COMM | FUNCTSEL_RESET | 0);
if(!WriteCOM(portnum,1,buff))
return FALSE;
Sleep(5);
FlushCOM(portnum);
return TRUE; // return success
}
//-------------------------------------------------------------------
// Description:
// Closes the connection to the port.
//
// portnum - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
//
// Returns FALSE if unsuccessful and TRUE if successful.
//
void CloseCOM(int portnum)
{
// clear port address (use as flag)
PortState[portnum].port_adr = 0;
// restore previous interrupt
_dos_setvect(PortState[portnum].com_vec_n, PortState[portnum].save_vec);
_disable(); // disable interrupts
// set bit (3 or 4) so it interrupts unmasked
outportb(0x21,(uchar)(~PortState[portnum].m8259_mask | inportb(0x21)));
// clear dlab in LCR
outportb(PortState[portnum].com.nam.lcr, (0x7f & inportb(PortState[portnum].com.nam.lcr)));
// clear interrupt on receive in IER
outportb(PortState[portnum].com.nam.b.ier, 0);
// rts and out2 off. leave dtr alone in MCR
//????????outportb(PortState[Prt].com.nam.mcr, (0x01 & inport(PortState[Prt].com.nam.mcr)));
_enable(); // re-enable interrupts
}
//-------------------------------------------------------------------
// Read an array of bytes to the COM port, verify that it was
// sent out. Assume that baud rate has been set and the buffers have
// been flushed.
//
// portnum - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
// inlen - the length of the data that was read
// outbuf - the input data
//
// Returns number of characters read
//
int ReadCOM(int portnum, int inlen, uchar *inbuf)
{
short cnt=0;
ulong far *sysclk = (ulong far *) 0x0040006c;
ulong M;
ulong more;
// get a time limit
M = *sysclk + 3;
// remember this as the last port
LastPrt = portnum;
// loop to get all of the characters or timeout
do
{
if (PortState[portnum].inbuf_n)
{
inbuf[cnt++] = PortState[portnum].inbuf[PortState[portnum].inbuf_get++]; // got it
PortState[portnum].inbuf_get &= INBUF_MASK; // wrap around
--PortState[portnum].inbuf_n; // one less char in buffer
}
}
while ((cnt < inlen) && (M > *sysclk));
// check for more
more = PortState[portnum].inbuf_n;
return cnt;
}
//-------------------------------------------------------------------
// Write an array of bytes to the COM port, verify that it was
// sent out. Assume that baud rate has been set and the buffers have
// been flushed.
//
// portnum - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
// outlen - the length of the data to be written
// outbuf - the output data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -