1 /*-------------------------------------------------------------------------
2 ser_ir.c - source file for serial routines
4 Written By - Josef Wolf <jw@raven.inka.de> (1999)
7 1.0 Bela Torok <bela.torok.kssg.ch> Jul. 2000
8 RTS / CTS protocol added
10 This program 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
15 This program 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 program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them. Help stamp out software-hoarding!
28 -------------------------------------------------------------------------*/
30 /* This file implements a serial interrupt handler and its supporting
31 * routines. Compared with the existing serial.c and _ser.c it has
32 * following advantages:
33 * - You can specify arbitrary buffer sizes (umm, up to 255 bytes),
34 * so it can run on devices with _little_ memory like at89cx051.
35 * - It won't overwrite characters which already are stored in the
36 * receive-/transmit-buffer.
39 /* BUG: those definitions (and the #include) should be set dynamically
40 * (while linking or at runtime) to make this file a _real_ library.
43 /* RTS/CTS protocol howto:
46 Shematic of cable for RTS/CTS protocol (B. Torok - Jun. 2000)
48 <- DB9 female connector -><- RS232 driver/receiver -><- 8051 system ->
49 connect to PC e.g. MAX232
56 Transmitters/Receivers
58 Pin2-----------------------------<<<-------------------TXD
61 Pin3----------------------------->>>-------------------RXD
64 Pin5---------------------------------------------------GND
67 Pin6---Pin8----------------------<<<-------------------CTS (see #define CTS)
70 Pin7----------------------------->>>-------------------RTS (see #define RTS)
78 #define RXBUFLEN 18 // The minimum rx buffer size for safe communications
79 // is 17. (The UART in the PC has a 16-byte FIFO.)
80 // TXBUFLEN & RXBUFLEN can be highher if rxbuf[] and txbuf[] is in xdata, max size is limited to 256!
86 #define CTS P3_6 // CTS & RTS can be assigned to any free pins
89 // You might want to specify idata, pdata or xdata for the buffers
90 static unsigned char rxbuf[RXBUFLEN], txbuf[TXBUFLEN];
91 static unsigned char rxcnt, txcnt, rxpos, txpos;
97 rxcnt = txcnt = rxpos = txpos = 0; // init buffers
99 SCON = 0x50; // mode 1 - 8-bit UART
100 PCON |= 0x80; // SMOD = 1;
101 TMOD &= 0x0f; // use timer 1
103 // TL1 = TH1 = 256 - 104; // 600bps with 12 MHz crystal
104 // TL1 = TH1 = 256 - 52; // 1200bps with 12 MHz crystal
105 // TL1 = TH1 = 256 - 26; // 2400bps with 12 MHz crystal
106 TL1 = TH1 = 256 - 13; // 4800bps with 12 MHz crystal
108 TR1 = 1; // Enable timer 1
114 void ser_handler(void) interrupt 4
118 /* don't overwrite chars already in buffer */
119 if(rxcnt < RXBUFLEN) rxbuf [(unsigned char)(rxpos + rxcnt++) % RXBUFLEN] = SBUF;
120 if(rxcnt >= (RXBUFLEN - THRESHOLD)) CTS = DISABLE;
125 if (busy = txcnt) { /* Assignment, _not_ comparison! */
127 SBUF = txbuf[txpos++];
128 if(txpos >= TXBUFLEN) txpos = 0;
133 void ser_putc(unsigned char c)
135 while(txcnt >= TXBUFLEN); // wait for room in buffer
137 while(RTS == DISABLE);
141 txbuf[(unsigned char)(txpos + txcnt++) % TXBUFLEN] = c;
149 unsigned char ser_getc(void)
153 while (!rxcnt) { // wait for a character
160 if (rxpos >= RXBUFLEN) rxpos = 0;
167 void ser_puts(unsigned char *s)
171 if (c == '\n') ser_putc('\r');
177 void ser_gets(unsigned char *s, unsigned char len)
179 unsigned char pos, c;
184 if (c == '\r') continue; // discard CR's
186 if (c == '\n') break; // NL terminates
188 s[pos] = '\0'; // terminate string
191 unsigned char ser_can_xmt(void)
193 return TXBUFLEN - txcnt;
196 unsigned char ser_can_rcv(void)