udoslnk.c
来自「DALLAS 1 Wire 总线 SDK 支持多种高级语言」· C语言 代码 · 共 699 行 · 第 1/2 页
C
699 行
//
// Returns TRUE for success and FALSE for failure
//
int WriteCOM(int portnum, int outlen, uchar *outbuf)
{
short cnt=0;
// remember this as the last port
LastPrt = portnum;
// loop to write out each byte an wait until sent
while (cnt < outlen)
{
// check if output buffer empty
if (inportb(PortState[portnum].com.nam.lsr) & 0x20)
{
// make sure interrupts are enabled
_enable();
// send out a character
outportb(PortState[portnum].com.nam.a.tbr,outbuf[cnt++]);
}
}
return outlen;
}
//------------------------------------------------------------------
// Description:
// This routines sets up the DCB and performs a SetCommState().
// SetupCOM assumes OpenComm has previously been called.
// Returns 0 if unsuccessful and 1 if successful.
//
// Prt - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
// baudrate - the baudrate that should be used in setting up the port.
//
// return TRUE if the port was setup correctly
//
SMALLINT SetupCOM(int portnum, ulong baudrate)
{
ushort reload;
// set dlab to load reload of 8250 in LCR
outportb(PortState[portnum].com.nam.lcr, 0x80);
// calculat the reload
switch (baudrate)
{
case 9600: reload = 12;
break;
case 19200: reload = 6;
break;
case 57600: reload = 2;
break;
case 115200: reload = 1;
break;
default: reload = 12;
break;
};
// load msb of Reload
outportb(PortState[portnum].com.nam.b.msb, reload / 256);
// load lsb of Reload
outportb(PortState[portnum].com.nam.a.lsb, reload & 0xFF);
// parity off, stop=1, word=8 in LCR
outportb(PortState[portnum].com.nam.lcr, 3);
//?????outportb(PortState[Prt].com.nam.lcr, 0x07); // 2 stop bits for test
// enable 16550 hokie1
outportb(PortState[portnum].com.nam.iir,0xC7);
// disable 16550 fifos
// commented out because you can do the hardware enable
// or this option chooses software fifo.
// outportb(PortState[portnum].com.nam.iir,0x00);
return TRUE;
}
//-------------------------------------------------------------------
// Description:
// flush the rx and tx buffers
//
// portnum - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
//
void FlushCOM(int portnum)
{
// loop to flush the send buffers
while ((inportb(PortState[portnum].com.nam.lsr) & 0x60) != 0x60)
;
// read any bytes in input buffer
while (inportb(PortState[LastPrt].com.nam.lsr) & 0x01)
inportb(PortState[LastPrt].com.nam.a.rbr);
// clear the interrupt
inportb(PortState[LastPrt].com.nam.iir);
// non-specific return from interrupt
outportb(0x20,0x20);
_disable(); // disable interrupts
// reset the buffer counters
PortState[portnum].inbuf_n = 0;
PortState[portnum].inbuf_get = 0;
PortState[portnum].inbuf_put = 0;
_enable(); // re-enble interrupts
}
//--------------------------------------------------------------------------
// ISR for com port receive.
//
void __interrupt __far com_serial_int4(ushort _es, ushort _ds, ushort _di, ushort _si,
ushort _bp, ushort _sp, ushort _bx, ushort _dx,
ushort _cx, ushort _ax, ushort _ip, ushort _cs,
ushort _flags)
{
_disable(); // disable interrupts
// get uart status
if (inportb(PortState[LastPrt].com.nam.lsr) & 0x01)
{
// get the character
PortState[LastPrt].inbuf[PortState[LastPrt].inbuf_put++] = inportb(PortState[LastPrt].com.nam.a.rbr);
// wrap buffer
PortState[LastPrt].inbuf_put &= INBUF_MASK;
// count the new character
PortState[LastPrt].inbuf_n++;
}
// clear the interrupt
inportb(PortState[LastPrt].com.nam.iir);
// non-specific return from interrupt
outportb(0x20,0x20);
_enable(); // re-enable interrupts
}
//--------------------------------------------------------------------------
// ISR for com port receive.
//
void __interrupt __far com_serial_int3(ushort _es, ushort _ds, ushort _di, ushort _si,
ushort _bp, ushort _sp, ushort _bx, ushort _dx,
ushort _cx, ushort _ax, ushort _ip, ushort _cs,
ushort _flags)
{
_disable(); // disable interrupts
// get uart status
if (inportb(PortState[LastPrt].com.nam.lsr) & 0x01)
{
// get the character
PortState[LastPrt].inbuf[PortState[LastPrt].inbuf_put++] = inportb(PortState[LastPrt].com.nam.a.rbr);
// wrap buffer
PortState[LastPrt].inbuf_put &= INBUF_MASK;
// count the new character
PortState[LastPrt].inbuf_n++;
}
// clear the interrupt
inportb(PortState[LastPrt].com.nam.iir);
// non-specific return from interrupt
outportb(0x20,0x20);
_enable(); // re-enable interrupts
}
//-------------------------------------------------------------------
// Description:
// Send a break on the com port for "len" msec
//
// portnum - number 0 to MAX_PORTNUM-1. This number is provided to
// indicate the symbolic port number.
//
void BreakCOM(int portnum)
{
// start the break
outportb(PortState[portnum].com.nam.lcr, 0x43);
Sleep(2);
// clear the break
outportb(PortState[portnum].com.nam.lcr, 0x03);
}
//--------------------------------------------------------------------------
// Set the baud rate on the com port.
//
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
// OpenCOM to indicate the port number.
// 'new_baud' - new baud rate defined as
// PARMSET_9600 0x00
// PARMSET_19200 0x02
// PARMSET_57600 0x04
// PARMSET_115200 0x06
//
void SetBaudCOM(int portnum, uchar new_baud)
{
ushort reload;
// set dlab to load reload of 8250 in LCR
outportb(PortState[portnum].com.nam.lcr, 0x80);
// calculate the reload
// does not support PARMSET_57600
// and PARMSET_115200
switch(new_baud)
{
case PARMSET_9600: reload = 12;
break;
case PARMSET_19200: reload = 6;
break;
case PARMSET_57600: reload = 2;
break;
case PARMSET_115200: reload = 1;
break;
default: reload = 12;
break;
};
// load msb of Reload
outportb(PortState[portnum].com.nam.b.msb, reload / 256);
// load lsb of Reload
outportb(PortState[portnum].com.nam.a.lsb, reload & 0xFF);
// parity off, stop=1, word=8 in LCR
outportb(PortState[portnum].com.nam.lcr, 3);
}
//--------------------------------------------------------------------------
// Description:
// Drop and then raise power (DTR,RTS) on the com port
//
// len > 0 - drop power for len ms
// = 0 - reset power drop
// < 0 - drop power for an infinite time
//
void PowerCOM(int portnum, short len)
{
// drop power?
if (len != 0)
// DTR/RTS off
outportb(PortState[portnum].com.nam.mcr,0);
if (len > 0)
// sleep
Sleep(len);
// is this not an infinite power drop?
if (len >= 0)
// DTR/RTS on
outportb(PortState[portnum].com.nam.mcr,0x0B);
}
//--------------------------------------------------------------------------
// Mark time stamp for later comparison
//
void MarkTime(void)
{
// get the rought timestamp
BigTimeStamp = msGettick();
// get an accurate timestamp
outportb(0x43,0); // freeze value in timer
TimeStamp = inportb(0x40) & 0xFF; // read value in timer
TimeStamp += (inportb(0x40) << 8) & 0xFF00;
}
//--------------------------------------------------------------------------
// Check if timelimit number of ms have elapse from the call to MarkTime
//
// timelimit - the time limit for the elapsed time
//
// Return TRUE if the time has elapse else FALSE.
//
SMALLINT ElapsedTime(long timelimit)
{
ulong C,N;
// check if using rought or accurate timestamp
if (timelimit > 5)
{
// check if time elapsed
return ((BigTimeStamp + timelimit) < (ulong) msGettick());
}
else
{
outportb(0x43,0); // freese value in timer
N = inportb(0x40) & 0xFF; // read value in timer
N += (inportb(0x40) << 8) & 0xFF00;
if (TimeStamp < N)
C = 65536 - (N - TimeStamp);
else
C = TimeStamp - N;
// check if time elapsed
return ((timelimit * MilliSec) < C);
}
}
//--------------------------------------------------------------------------
// Delays for the given amout of time
//
// len - the number of milliseconds to sleep
//
void msDelay(int len)
{
Sleep(len);
}
//--------------------------------------------------------------------------
// Wait duration in ms
//
void Sleep(long len)
{
// get a time stamp
MarkTime();
// wait for len ms
while (!ElapsedTime(len));
}
//--------------------------------------------------------------------------
// Get the current millisecond tick count. Does not have to represent
// an actual time, it just needs to be an incrementing timer.
//
long msGettick(void)
{
ulong *sysclk = (ulong *) 0x0040006c;
return *sysclk * 55;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?