📄 serial.c
字号:
/******************************************************************************/
/* */
/* SERIAL.C: Interrupt Controlled Serial Interface for RTX-166 tiny */
/* */
/******************************************************************************/
#include <reg166.h> /* special function register 80C166 */
#include <rtx166t.h> /* RTX-166 tiny functions & defines */
#include <intrins.h> /* C166 intrinsic functions */
#define OLEN 8 /* size of serial transmission buffer */
unsigned char ostart; /* transmission buffer start index */
unsigned char oend; /* transmission buffer end index */
char outbuf[OLEN]; /* storage for transmission buffer */
int otask = -1; /* task number of output task */
#define ILEN 8 /* size of serial receiving buffer */
unsigned char istart; /* receiving buffer start index */
unsigned char iend; /* receiving buffer end index */
char inbuf[ILEN]; /* storage for receiving buffer */
int itask = -1; /* task number of output task */
#define CTRL_Q 0x11 /* Control+Q character code */
#define CTRL_S 0x13 /* Control+S character code */
bit sendfull; /* flag: marks transmit buffer full */
bit sendactive; /* flag: marks transmitter active */
bit sendstop; /* flag: marks XOFF character */
/******************************************************************************/
/* putbuf: write a character to SBUF or transmission buffer */
/******************************************************************************/
void putbuf (char c) {
if (!sendfull) { /* transmit only if buffer not full */
if (!sendactive && !sendstop) { /* if transmitter not active: */
sendactive = 1; /* transfer the first character direct */
S0TBUF = c; /* to S0TBUF to start transmission */
}
else { /* otherwise: */
S0TIE = 0; /* disable transmit interrupt */
_nop_ (); /* avoid pipeline effects */
_nop_ ();
outbuf[oend++ & (OLEN-1)] = c; /* transfer char to transmission buffer */
if (((oend ^ ostart) & (OLEN-1)) == 0) sendfull = 1;
S0TIE = 1; /* enable transmit interrupt */
} /* set flag if buffer is full */
}
}
/******************************************************************************/
/* putchar: interrupt controlled putchar function */
/******************************************************************************/
char putchar (char c) {
if (c == '\n') { /* expand new line character: */
while (sendfull) { /* wait for transmission buffer empty */
otask = os_running_task_id (); /* set output task number */
os_wait (K_SIG, 0, 0); /* RTX-166 call: wait for signal */
otask = -1; /* clear output task number */
}
putbuf (0x0D); /* send CR before LF for <new line> */
}
while (sendfull) { /* wait for transmission buffer empty */
otask = os_running_task_id (); /* set output task number */
os_wait (K_SIG, 0, 0); /* RTX-166 call: wait for signal */
otask = -1; /* clear output task number */
}
putbuf (c); /* send character */
return (c); /* return character: ANSI requirement */
}
/******************************************************************************/
/* _getkey: interrupt controlled _getkey */
/******************************************************************************/
char _getkey (void) {
char c;
while (iend == istart) {
itask = os_running_task_id (); /* set input task number */
os_wait (K_SIG, 0, 0); /* RTX-166 call: wait for signal */
itask = -1; /* clear input task number */
}
S0RIE = 0; /* disable receiver interrupt */
_nop_ (); /* avoid pipeline effects */
_nop_ ();
c = inbuf[istart++ & (ILEN-1)];
S0RIE = 1; /* enable receiver interrupt */
return (c);
}
/******************************************************************************/
/* serial_receive: serial receive interrupt */
/******************************************************************************/
void serial_receive (void) interrupt SERIAL_RECEIVE0 = 0x2B using S_RBANK {
unsigned char c;
c = S0RBUF; /* read character */
switch (c) { /* process character */
case CTRL_S:
sendstop = 1; /* if Control+S stop transmission */
break;
case CTRL_Q:
if (_testclear_ (sendstop)) { /* if Control+Q start transmission */
S0TIR = 1; /* by setting the interrupt request bit */
}
break;
default: /* read all other characters into inbuf */
if ((istart + ILEN) != iend) {
inbuf[iend++ & (ILEN-1)] = c;
}
/* if task waiting: signal ready */
if (itask != -1) isr_send_signal (itask);
break;
}
}
/******************************************************************************/
/* serial_transmit: serial transmitter interrupt */
/******************************************************************************/
void serial_transmit (void) interrupt SERIAL_TRANSMIT0 = 0x2A using S_RBANK {
if (ostart != oend) { /* if characters in buffer and */
if (!sendstop) { /* if not Control+S received */
S0TBUF = outbuf[ostart++ & (OLEN-1)]; /* transmit character */
sendfull = 0; /* clear 'sendfull' flag */
/* if task waiting: signal ready */
if (otask != -1) isr_send_signal (otask);
}
}
else sendactive = 0; /* if all transmitted clear 'sendactive' */
}
/******************************************************************************/
/* serial_init: initialize serial interface */
/******************************************************************************/
void serial_init (void) {
P3 |= 0x0400; /* set PORT 3.10 output latch (TXD) */
DP3 |= 0x0400; /* set PORT 3.10 direction control (TXD output) */
DP3 &= 0xF7FF; /* reset PORT 3.11 direction control (RXD input) */
S0TIC = 0x45; /* transmit interrupt enable; ILVL = 1; GLVL = 1 */
S0RIC = 0x46; /* receive interrupt enable; ILVL = 1; GLVL = 2 */
S0BG = 0x0A; /* set baudrate to 57600 BAUD */
S0CON = 0x8011; /* set serial mode */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -