struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / device / lib / ser_ir_cts_rts.c
blob3340a6f374d82205154b7c46e587871a6a41b872
1 /*-------------------------------------------------------------------------
2 ser_ir_cts_rts.c - source file for serial routines
4 Copyright (C) 1999, Josef Wolf <jw AT raven.inka.de>
6 Revisions:
7 1.0 Bela Torok <bela.torok.kssg.ch> Jul. 2000
8 RTS / CTS protocol added
10 This library is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
13 later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this library; see the file COPYING. If not, write to the
22 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
23 MA 02110-1301, USA.
25 As a special exception, if you link this library with other files,
26 some of which are compiled with SDCC, to produce an executable,
27 this library does not by itself cause the resulting executable to
28 be covered by the GNU General Public License. This exception does
29 not however invalidate any other reasons why the executable file
30 might be covered by the GNU General Public License.
31 -------------------------------------------------------------------------*/
33 /* This file implements a serial interrupt handler and its supporting
34 * routines. Compared with the existing serial.c and _ser.c it has
35 * following advantages:
36 * - You can specify arbitrary buffer sizes (umm, up to 255 bytes),
37 * so it can run on devices with _little_ memory like at89cx051.
38 * - It won't overwrite characters which already are stored in the
39 * receive-/transmit-buffer.
42 /* BUG: those definitions (and the #include) should be set dynamically
43 * (while linking or at runtime) to make this file a _real_ library.
46 /* RTS/CTS protocol howto:
49 Shematic of cable for RTS/CTS protocol (B. Torok - Jun. 2000)
51 <- DB9 female connector -><- RS232 driver/receiver -><- 8051 system ->
52 connect to PC e.g. MAX232
54 RS232 TTL
55 level level
57 DCD DTR
58 Pin1---Pin4
59 Transmitters/Receivers
60 RXD
61 Pin2-----------------------------<<<-------------------TXD
63 TXD
64 Pin3----------------------------->>>-------------------RXD
66 GND
67 Pin5---------------------------------------------------GND
69 DSR CTS
70 Pin6---Pin8----------------------<<<-------------------CTS (see #define CTS)
72 RTS
73 Pin7----------------------------->>>-------------------RTS (see #define RTS)
77 #include <8051.h>
78 #include "ser_ir.h"
80 #define TXBUFLEN 3
81 #define RXBUFLEN 18 // The minimum rx buffer size for safe communications
82 // is 17. (The UART in the PC has a 16-byte FIFO.)
83 // TXBUFLEN & RXBUFLEN can be highher if rxbuf[] and txbuf[] is in xdata, max size is limited to 256!
85 #define THRESHOLD 16
86 #define ENABLE 0
87 #define DISABLE 1
89 #define CTS P3_6 // CTS & RTS can be assigned to any free pins
90 #define RTS P3_7
92 // You might want to specify idata, pdata or xdata for the buffers
93 static unsigned char rxbuf[RXBUFLEN], txbuf[TXBUFLEN];
94 static unsigned char rxcnt, txcnt, rxpos, txpos;
95 static __bit busy;
97 void
98 ser_init ()
100 ES = 0;
101 rxcnt = txcnt = rxpos = txpos = 0; // init buffers
102 busy = 0;
103 SCON = 0x50; // mode 1 - 8-bit UART
104 PCON |= 0x80; // SMOD = 1;
105 TMOD &= 0x0f; // use timer 1
106 TMOD |= 0x20;
107 // TL1 = TH1 = 256 - 104; // 600bps with 12 MHz crystal
108 // TL1 = TH1 = 256 - 52; // 1200bps with 12 MHz crystal
109 // TL1 = TH1 = 256 - 26; // 2400bps with 12 MHz crystal
110 TL1 = TH1 = 256 - 13; // 4800bps with 12 MHz crystal
112 TR1 = 1; // Enable timer 1
113 ES = 1;
115 CTS = ENABLE;
118 void
119 ser_handler (void) interrupt (4)
121 if (RI) {
122 RI = 0;
123 /* don't overwrite chars already in buffer */
124 if(rxcnt < RXBUFLEN) rxbuf [(unsigned char)(rxpos + rxcnt++) % RXBUFLEN] = SBUF;
125 if(rxcnt >= (RXBUFLEN - THRESHOLD)) CTS = DISABLE;
128 if (TI) {
129 TI = 0;
130 if (busy = txcnt) { // Assignment, _not_ comparison!
131 txcnt--;
132 SBUF = txbuf[txpos++];
133 if(txpos >= TXBUFLEN) txpos = 0;
138 void
139 ser_putc (unsigned char c)
141 while(txcnt >= TXBUFLEN); // wait for room in buffer
143 while(RTS == DISABLE);
145 ES = 0;
146 if (busy) {
147 txbuf[(unsigned char)(txpos + txcnt++) % TXBUFLEN] = c;
148 } else {
149 SBUF = c;
150 busy = 1;
152 ES = 1;
155 unsigned char
156 ser_getc (void)
158 unsigned char c;
160 while (!rxcnt) { // wait for a character
161 CTS = ENABLE;
164 ES = 0;
165 rxcnt--;
166 c = rxbuf[rxpos++];
167 if (rxpos >= RXBUFLEN) rxpos = 0;
168 ES = 1;
169 return (c);
172 #pragma save
173 #pragma noinduction
174 void
175 ser_puts (unsigned char *s)
177 unsigned char c;
178 while (c= *s++) {
179 if (c == '\n') ser_putc('\r');
180 ser_putc (c);
183 #pragma restore
185 void
186 ser_gets (unsigned char *s, unsigned char len)
188 unsigned char pos, c;
190 pos = 0;
191 while (pos <= len) {
192 c = ser_getc();
193 if (c == '\r') continue; // discard CR's
194 s[pos++] = c;
195 if (c == '\n') break; // NL terminates
197 s[pos] = '\0'; // terminate string
200 unsigned char
201 ser_can_xmt (void)
203 return TXBUFLEN - txcnt;
206 unsigned char
207 ser_can_rcv (void)
209 return rxcnt;