📄 serdpcin.c
字号:
}
else /* rxcount > 0 */
{
/*
Get remainder of Block of data from the serial port, recsize characters
and store them in rxbuf
*/
if ((rxchar = waitforchar()) >= 0) /* no errors */
{
/*
Check Phase bit
*/
if (rxchar & 0x80) /* check to see that phase bit = '0' */
{
if (outputmode == STREAM)
{
phaseerror_count++; /* keep track of phase errors */
resynch = TRUE; /* loop again flag */
continue;
}
else
{
return(RXPHASEERROR); /* return phase error */
}
}
}
else
{
if (outputmode == STREAM)
{
phaseerror_count++; /* keep track of phase errors */
resynch = TRUE; /* loop again flag */
continue;
}
else
{
return(RXERRORS);
}
}
}
/*
Store the received character
*/
*rxbufptr++ = rxchar; /* store and adjust pointer */
rxcount++; /* increment */
}
while ((resynch) || (rxcount < recsize));
/*
Return the number of characters received
*/
return(rxcount);
}
/*
send_serial_cmd - Send Serial Command to the Bird port
Prototype in: serial.h
Parameters Passed: cmd - string to send to the serial point
cmdsize - size of the cmd string (cmd is NOT
NULL terminated, since the data can
be NULL)
Return Value: number of characters transmitted
Remarks: Routine will send a string of characters to the serial
port. The string is pointed to by cmd and all
characters will be sent upto but NOT including
the NULL
*/
int send_serial_cmd(cmd,cmdsize)
unsigned char * cmd;
short cmdsize;
{
short txcount = 0;
unsigned char rs232tofbbcmd;
DISABLE();
/*
Send the RS232 to FBB Prefice Character if non-zero
*/
if (rs232tofbbaddr > 0)
{
if (rs232tofbbaddr <= 15)
/* pass through command 0-15 */
rs232tofbbcmd = (unsigned char)(0xF0 | rs232tofbbaddr);
else
/* pass through command 16-31 */
rs232tofbbcmd = (unsigned char)(0xE0 | rs232tofbbaddr-16);
while (send_serial_char(rs232tofbbcmd) == TXNOTEMPTY);
}
while (txcount < cmdsize)
{
/*
Store the character in the TX buffer
*/
if (send_serial_char(*cmd++) != TRUE)
break;
txcount++;
}
/*
Verify that the TX interrupt is enabled
..if not, enable it so that the ISR will execute
*/
if ((INPORTB (com_base + INTERENABLE) & TXHOLDINTENABLE) == 0)
{
OUTPORTB (com_base + INTERENABLE,
TXHOLDINTENABLE | RXDATAAVAILINTENABLE | RXLINESTATUSINTENABLE);
OUTPORTB (com_base + INTERENABLE,
TXHOLDINTENABLE | RXDATAAVAILINTENABLE | RXLINESTATUSINTENABLE);
}
ENABLE(); /* reenable interrupts */
return(txcount);
}
/*
send_serial_char - Send one serial char to the serial port
Prototype in: serial.h
Parameters Passed: chr - character to send to the serial port
Return Value: returns TRUE if successful, or TXBUFFERFULL if the
TXBUF is full
Remarks: The routine is used to send a single character
out to the UART if there is room in the output buffer.
The routine checks to see if the Transmit interrupts
are presently enabled...if not they are turned out
so the ISR will get the character.
*/
int send_serial_char(chr)
unsigned char chr;
{
/*
Check for a full TX buffer...
... 2 ways the txbufinptr can = the txbufoutptr:
1) if the buffer is empty, which is OK
2) if the buffer is full, which is not OK
*/
if (txbufinptr == txbufoutptr)
if (!txbufempty)
return(TXBUFFERFULL);
/*
Write the character to the inbufptr
*/
*txbufinptr++ = chr;
txbufempty = FALSE;
/*
Check for buffer end...wrap around if at end
*/
if (txbufinptr == &txbuf[TXBUFSIZE])
txbufinptr = txbuf;
return(TRUE);
}
/*
get_serial_char - Get 1 Character from the serial port if one is available
Prototype in: serial.h
Parameters Passed: void
Return Value: returns the
Remarks: returns the receive character if successful,
RXERRORS if recieve errors
NODATAAVAIL if no characer available
*/
int get_serial_char()
{
short rxchar;
if ((!rxerrors) && (!rxbufoverruns))
{
/*
get character if available...else return
*/
if (rxbufinptr == rxbufoutptr)
return(NODATAAVAIL);
/*
get the character
*/
rxchar = *rxbufoutptr++;
/*
check for End of Rx buffer..if so, wrap pointer to start
*/
if (rxbufoutptr == &rxbuf[RXBUFSIZE])
rxbufoutptr = rxbuf;
/*
return the character
*/
return(rxchar);
}
else
{
/*
Reset Error flags and Announce the Errors
*/
if (rxerrors)
{
printf("** ERROR ** rx line errors have occured\n");
rxerrors = FALSE;
}
if (rxbufoverruns)
{
printf("** ERROR ** rx buffer overrun errors have occured\n");
rxbufoverruns = FALSE;
}
return(RXERRORS);
}
}
/*
waitforchar - Wait for a Character from the Serial Port
Prototype in: serial.h
Parameters Passed: void
Return Value: returns the receive character if successful,
RXERRORS if recieve errors,
RXTIMEOUT if a time out occurs before a
character is ready
Remarks: Routine waits for the TIMEOUTINTICKS period
for a character
*/
int waitforchar()
{
short rxchar;
long starttime;
/*
Get the time now in ticks
*/
starttime = GETTICKS;
/*
Wait until a character is available
....leave loop if errors or character available
*/
while ((rxchar = get_serial_char()) == NODATAAVAIL)
{
/*
Check to see if a timeout occured
*/
if ((GETTICKS - starttime) > (long)((RXTIMEOUTINSECS * 1000) / TICK_MSECS))
{
printf("\n** ERROR ** receiver timed out\n");
return(RXTIMEOUT);
}
}
/*
return if RX errors
*/
if (rxchar < 0)
return(RXERRORS);
/*
Everything is OK...return the character
*/
return(rxchar);
}
/*
waitforphase - Wait for a Character with phase bit set
Prototype in: serial.h
Parameters Passed: void
Return Value: returns the received character if successful,
or RXERRORS if an error occurs
Remarks: waits for a character to be received with the
most significant bit (bit 7) set to a '1'. Characters
received with bit 7 = '0' are thrown away.
Routine waits for the TIMEOUTINTICKS period.
*/
int waitforphase()
{
short rxchar;
/*
Wait until waitforchar returns a character or error
*/
while (((rxchar = waitforchar()) & 0x80) == 0)
{
/*
return if errors
*/
if (rxchar < 0)
return(RXERRORS);
}
/*
Everything is OK...return the character
*/
return(rxchar);
}
/*
serialisr - Serial Interrupt Service Routine
Prototype in: serial.h
Parameters Passed: void
Return Value: void
Remarks: Routine processes the interrupt request from the
8250 UART. There are four possible interrupts from
the UART...all are processed while in the ISR.
Note that for the HIGHC users, the routine is
called from the assembly module, which has
set the DS to our own Data Segment, which will
allow DOS to be interruptable since DOS will be
operating in REAL mode via the DOS Extender
*/
#ifdef HIGHC
void serialisr(void) /* called from the assembly code */
#else
INTTYPE serialisr()
#endif
{
short intid; /* holds the interrupt ID from the UART */
short txchar; /* Character to transmit */
#ifndef DPMC
ENABLE(); /* enable higher priority interrupts to occur */
#endif
/*
Verify that the Interrupt is from the UART
...do all the possible pending interrupts while here...until
there are NO interrupts pending
*/
while (!((intid = INPORTB(com_base + INTERIDENT)) & 1)) /* bit 0 = 0 if interrupts pending */
{
/*
Do the Serial Interrupt in Priority order
..RXLINESTATUS, RXDATAAVAIL,TXEMPTY, MODEMSTATUS
*/
switch (intid)
{
/*
Line Status
...just increment error counter
*/
case RXLINESTATUS: /* line status changed ... check RX errors */
/*
Get the error from Linestatus
*/
if ((rxerrorvalue = (INPORTB(com_base + LINESTATUS) & RXERRORMSK)) != 0) /* clears interrupt */
rxerrors = TRUE;
break;
/*
RX Data Available
...get the byte and store it in the RX circular buffer
.....check for RX buffer overruns when storing character
*/
case RXDATAAVAIL:
/*
Get the RX data and store in the circular buffer
*/
*rxbufinptr++ = INPORTB(com_base + RXBUF);
/*
Check for RX circular buffer overrun
*/
if (rxbufinptr == rxbufoutptr) /* ck overrrun? */
rxbufoverruns=TRUE; /* increment overrun count */
/*
Check for top of buffer...adjust if necessary
*/
if (rxbufinptr == &rxbuf[RXBUFSIZE]) /* at top ? */
rxbufinptr = rxbuf; /* reset */
break;
/*
TX Holding Register Empty
...transmit a character from the TX buffer if one is available
else, shut down the TX interrupt until more characters are
available
*/
case TXEMPTY:
/*
Get the Character to transmit
*/
txchar = *txbufoutptr++;
/*
check for top of buffer
...reset if at top
*/
if (txbufoutptr == &txbuf[TXBUFSIZE])
txbufoutptr = txbuf;
if (txbufoutptr == txbufinptr) /* no data to send */
{
/*
Disable the Tx Interrupt Enable
....don't bother until more TX chars in buffer
*/
OUTPORTB(com_base + INTERENABLE,
RXDATAAVAILINTENABLE | RXLINESTATUSINTENABLE);
OUTPORTB(com_base + INTERENABLE,
RXDATAAVAILINTENABLE | RXLINESTATUSINTENABLE);
/*
Set flag to indicate buffer empty
*/
txbufempty = TRUE;
}
/*
Send the next TX character and increment the pointer
*/
OUTPORTB(com_base + TXBUF, txchar);
break;
/*
Modem Status Change
...currently should never get here since it is never enabled,
but if we do...clear the request by reading the register
*/
case MODEMSTATUSCHG: /* CTS, DSR, RI, DCD change */
INPORTB(com_base + MODEMSTATUS); /* clear the request */
}
}
/*
Send End of Interrupt Command to the 8259
*/
PCPIC_OUTEOI;
return; /* go home via IRET */
}
#endif /* DOS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -