diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /device/lib/ser_ir.c | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'device/lib/ser_ir.c')
| -rw-r--r-- | device/lib/ser_ir.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/device/lib/ser_ir.c b/device/lib/ser_ir.c new file mode 100644 index 0000000..75c09ab --- /dev/null +++ b/device/lib/ser_ir.c @@ -0,0 +1,154 @@ +/*------------------------------------------------------------------------- + ser_ir.h - source file for serial routines + + Copyright (C) 1999, Josef Wolf <jw AT raven.inka.de> + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this library; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + + As a special exception, if you link this library with other files, + some of which are compiled with SDCC, to produce an executable, + this library does not by itself cause the resulting executable to + be covered by the GNU General Public License. This exception does + not however invalidate any other reasons why the executable file + might be covered by the GNU General Public License. +-------------------------------------------------------------------------*/ + +#include "ser_ir.h" + +/* This file implements a serial interrupt handler and its supporting +* routines. Compared with the existing serial.c and _ser.c it has +* following advantages: +* - You can specify arbitrary buffer sizes (umm, up to 255 bytes), +* so it can run on devices with _little_ memory like at89cx051. +* - It won't overwrite characters which already are stored in the +* receive-/transmit-buffer. +*/ + +/* BUG: those definitions (and the #include) should be set dynamically +* (while linking or at runtime) to make this file a _real_ library. +*/ +#include <8051.h> +#define XBUFLEN 4 +#define RBUFLEN 8 + +/* You might want to specify idata, pdata or xdata for the buffers */ +static unsigned char __pdata rbuf[RBUFLEN], xbuf[XBUFLEN]; +static unsigned char rcnt, xcnt, rpos, xpos; +static __bit busy; + +void +ser_init (void) +{ + ES = 0; + rcnt = xcnt = rpos = xpos = 0; /* init buffers */ + busy = 0; + SCON = 0x50; + PCON |= 0x80; /* SMOD = 1; */ + TMOD &= 0x0f; /* use timer 1 */ + TMOD |= 0x20; + TL1 = -3; TH1 = -3; TR1 = 1; /* 19200bps with 11.059MHz crystal */ + ES = 1; +} + +void +ser_handler (void) __interrupt 4 +{ + if (RI) { + RI = 0; + /* don't overwrite chars already in buffer */ + if (rcnt < RBUFLEN) + rbuf [(unsigned char)(rpos+rcnt++) % RBUFLEN] = SBUF; + } + if (TI) { + TI = 0; + if (busy = xcnt) { /* Assignment, _not_ comparison! */ + xcnt--; + SBUF = xbuf [xpos++]; + if (xpos >= XBUFLEN) + xpos = 0; + } + } +} + +void +ser_putc (unsigned char c) +{ + while (xcnt >= XBUFLEN) /* wait for room in buffer */ + ; + ES = 0; + if (busy) { + xbuf[(unsigned char)(xpos+xcnt++) % XBUFLEN] = c; + } else { + SBUF = c; + busy = 1; + } + ES = 1; +} + +unsigned char +ser_getc (void) +{ + unsigned char c; + while (!rcnt) /* wait for character */ + ; + ES = 0; + rcnt--; + c = rbuf [rpos++]; + if (rpos >= RBUFLEN) + rpos = 0; + ES = 1; + return (c); +} + +#pragma save +#pragma noinduction +void +ser_puts (unsigned char *s) +{ + unsigned char c; + while (c=*s++) { + if (c == '\n') ser_putc ('\r'); + ser_putc (c); + } +} +#pragma restore + +void +ser_gets (unsigned char *s, unsigned char len) +{ + unsigned char pos, c; + + pos = 0; + while (pos <= len) { + c = ser_getc (); + if (c == '\r') continue; /* discard CR's */ + s[pos++] = c; + if (c == '\n') break; /* NL terminates */ + } + s[pos] = '\0'; +} + +unsigned char +ser_can_xmt (void) +{ + return XBUFLEN - xcnt; +} + +unsigned char +ser_can_rcv (void) +{ + return rcnt; +} |
