?? rs232.c
字號:
if(! rs_portopen) /* is a port open? */
return -1;
if(! rs_ds.rcv_cnt) /* char available ? */
return -1;
return (int)(*(rs_ss.in_buf + rs_ds.in_tail));
}
/* rs_getbyt: Return next available character from input buffer - return
-1 if none are available */
int rs_getbyt(void)
{
extern struct rs_statics rs_ss;
extern volatile struct rs_dynamics rs_ds;
extern int rs_portopen;
unsigned char rs_byt;
if(! rs_portopen) /* is a port open? */
return -1;
if(! rs_ds.rcv_cnt) /* char available ? */
return -1;
rs_byt = *(rs_ss.in_buf + rs_ds.in_tail++);
rs_ds.rcv_cnt--;
rs_ds.in_tail &= rs_ss.ibuf_siz;
return (int)rs_byt;
}
/* rs_getstr: Get specified number of bytes from port buffer and place in
user specified buffer. Null terminate string. If receive buffer
has fewer than the requested number of characters available, copy all
that are available. Return number of bytes copied. If rs_getcnt is 0,
copy characters until a nul is encountered (include it in getbuf) */
int rs_getstr(int rs_getcnt,char *rs_getbuf)
{
extern struct rs_statics rs_ss;
extern int rs_portopen;
int rs_x = 0;
int rs_c,rs_y;
if(! rs_portopen) /* is a port open? */
return -1;
if(rs_getcnt) /* was number of characters specified? */
rs_y = rs_getcnt;
else
rs_y = rs_ss.ibuf_siz;
while(rs_x < rs_y){
if((rs_c = rs_getbyt()) < 0)
break;
else
*(rs_getbuf + rs_x++) = (char)rs_c;
if(! rs_getcnt){ /* if no length specified, end when nul is encountered */
if(! rs_c)
break;
}
}
if(rs_getcnt) /* nul terminate if need be */
*(rs_getbuf + rs_x) = '\0';
return rs_x;
}
/* rs_inrcvd: Return number of received bytes waiting to be read from input
buffer. */
unsigned rs_inrcvd(void)
{
extern volatile struct rs_dynamics rs_ds;
extern struct rs_statics rs_ss;
if(rs_ds.rcv_cnt > rs_ss.ibuf_siz + 1){
rs_ds.rcv_cnt = rs_ss.ibuf_siz + 2;
return(rs_ss.ibuf_siz + 1);
}
else
return rs_ds.rcv_cnt;
}
/* rs_error: Return last error detected as follows:
bit 0: 1 = Buffer overrun
bit 1: 1 = Receive data overrun
bit 2: 1 = Parity error
bit 3: 1 = Framing error
bit 4: 1 = Break detected
bit 7: 1 = Error in receive FIFO */
int rs_error(void)
{
extern struct rs_statics rs_ss;
extern volatile struct rs_dynamics rs_ds;
int rs_errtmp;
rs_errtmp = (int)(rs_ds.err_cod & 0x9E);
if(rs_ds.rcv_cnt > (rs_ss.ibuf_siz + 1)){ /* receive buffer overflow ? */
rs_errtmp |= 0x01; /* set flag */
rs_ds.rcv_cnt = rs_ss.ibuf_siz + 1;
}
rs_ds.err_cod = '\0';
return rs_errtmp;
}
/* rs_modctrl: If rs_cmd = 0, return value of modem status register as of
most recent change. If rs_cmd = 1, switch line determined by parameter1
on or off depending on whether parameter2 is 1 or 0. If rs_cmd = 2,
return contents of modem control register */
int rs_modctrl(int rs_cmd,...)
{
extern struct rs_statics rs_ss;
extern volatile struct rs_dynamics rs_ds;
extern int rs_portopen;
unsigned char rs_cntrl;
int rs_tmp = 0;
va_list rs_ap;
va_start(rs_ap,rs_cmd);
if(rs_portopen){
if(rs_cmd == 2)
rs_tmp = inportb(rs_ss.mcr);
else if(rs_cmd == 1){ /*manipulate control line (modem control reg.) */
rs_cntrl = (unsigned char)(va_arg(rs_ap,int));
if(va_arg(rs_ap,int))
rs_cntrl |= inportb(rs_ss.mcr);
else{
rs_cntrl ^= '\xFF';
rs_cntrl &= inportb(rs_ss.mcr);
}
outportb(rs_ss.mcr,rs_cntrl);
}
else{ /* get modem status register */
rs_tmp = (int)rs_ds.msr_cod;
rs_ds.msr_cod &= '\xF0';
}
}
else /* no port open */
rs_tmp = -1;
va_end(rs_ap);
return rs_tmp;
}
/* send break */
int rs_break(void)
{
extern struct rs_statics rs_ss;
extern volatile struct rs_dynamics rs_ds;
extern int rs_portopen;
unsigned char rs_tmp;
unsigned rs_time;
if(! rs_portopen) /* is a port open? */
return -1;
rs_tmp = (char)inportb(rs_ss.lcr);
while(rs_ds.out_tail != rs_ds.out_head)
if(rs_ds.ier_msk == '\x0D')
break;
while(!((inportb(rs_ss.lsr)) & '\x20'))
;
rs_tmp = inportb(rs_ss.lcr);
rs_time = rs_timer(1);
outportb(rs_ss.lcr,rs_tmp | '\x40');
while(rs_timer(1) - rs_time < 4)
;
outportb(rs_ss.lcr,rs_tmp);
return 0;
}
/* clear input buffer */
void rs_clrin(void)
{
extern struct rs_statics rs_ss;
extern volatile struct rs_dynamics rs_ds;
if(! rs_portopen) /* is a port open? */
return;
disable();
rs_ds.in_tail = rs_ds.in_head;
rs_ds.rcv_cnt = 0;
if(rs_ss.xmitfifo == 16) /* if FIFOs enabled */
outportb(rs_ss.fcr,'\x43'); /* clear RCVR FIFO */
enable();
}
/* clear output buffer */
void rs_clrout(void)
{
extern struct rs_statics rs_ss;
extern volatile struct rs_dynamics rs_ds;
if(! rs_portopen) /* is a port open? */
return;
disable();
rs_ds.out_tail = rs_ds.out_head;
if(rs_ss.xmitfifo == 16) /* if FIFOs enabled */
outportb(rs_ss.fcr,'\x45'); /* clear XMIT FIFO */
enable();
}
/* use BIOS keyboard buffer head and tail pointers to determine if a key
has been pressed */
int rs_keyhit(void)
{
volatile int far* rs_keytail;
volatile int far* rs_keyhead;
rs_keyhead = (int far*)MK_FP(0x40,0x1A);
rs_keytail = rs_keyhead + 1;
if(*rs_keytail == *rs_keyhead)
return 0;
else
return 1;
}
/* use BIOS data area tick count to as 10/182 sec. resolution timer. If
rs_cmd is 0, clear counter and return count up to that point. Id
rs_cmd is non-zero, return tick count from the point which timer is
last cleared. */
unsigned rs_timer(int rs_cmd)
{
volatile unsigned long far* rs_biosticks;
static long rs_startticks;
unsigned rs_tmp;
rs_biosticks = (unsigned long far*)MK_FP(0x40,0x6C);
if(rs_cmd){
if(*rs_biosticks >= rs_startticks)
return((unsigned)(*rs_biosticks - rs_startticks));
else
return((unsigned)(*rs_biosticks + 1573040UL - rs_startticks));
}
else{
if(*rs_biosticks >= rs_startticks)
rs_tmp = (unsigned)(*rs_biosticks - rs_startticks);
else
rs_tmp = (unsigned)(*rs_biosticks + 1573040UL - rs_startticks);
rs_startticks = *rs_biosticks;
}
return rs_tmp;
}
/* rs_setflow: rs_cmd = 0: Turn flow control off
rs_cmd = 1: Set flow control to hardware - Parameter1
is hardware line to monitor.
rs_cmd = 2: Set flow control to XON/XOFF - Parameter1
is character to use for XON, Parameter2
is character to use for XOFF.
rs_cmd = 3: Return status of flow control - 0 = output
normal, 1 = output halted
rs_cmd = 4: Insert control character in output stream.
Parameter1 is control character.
rs_cmd = 5: Manipulate hardware line. Parameter1 is bit
pattern corresponding to line to change.
If parameter2 is 0, line is turned off,
if 1, line is turned on*/
int rs_setflow(int rs_cmd,...)
{
extern struct rs_statics rs_ss;
extern volatile struct rs_dynamics rs_ds;
extern int rs_portopen;
int rs_ret = 0;
unsigned char rs_cntrl;
va_list rs_ap;
va_start(rs_ap, rs_cmd);
if(rs_portopen){
switch(rs_cmd){
case 0: /* turn flow control off */
rs_ss.flow = rs_cmd;
break;
case 1: /* set flow control to hardware */
rs_ss.flow = rs_cmd;
rs_ss.hdw_flw = ((char)(va_arg(rs_ap,int))) << 4;
if((inportb(rs_ss.msr)) & rs_ss.hdw_flw)
rs_ds.ier_msk = '\x0F';
else
rs_ds.ier_msk = '\x0D';
break;
case 2: /* set flow control to XON/XOFF */
rs_ss.flow = rs_cmd;
rs_ss.xon = (char)(va_arg(rs_ap,int));
rs_ss.xoff = (char)(va_arg(rs_ap,int));
break;
case 3: /* return status of flow control */
rs_ret = (rs_ds.ier_msk == '\x0D');
break;
case 4: /* insert control character in output stream */
rs_cntrl = (char)(va_arg(rs_ap,int));
#ifndef RS_POLLED_XMIT
outportb(rs_ss.ier,'\x0D');
#endif
while(!(inportb(rs_ss.lsr) & '\x20'))
;
outportb(rs_ss.thr,rs_cntrl);
#ifndef RS_POLLED_XMIT
outportb(rs_ss.ier,rs_ds.ier_msk);
#endif
break;
}
}
else /* no port open */
rs_ret = -1;
va_end(rs_ap);
return rs_ret;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -