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.
37 * - It checks receiver first to minimize probability for overruns
38 * in the serial receiver.
41 /* BUG: those definitions (and the #include) should be set dynamically
42 * (while linking or at runtime) to make this file a _real_ library.
45 /* RTS/CTS protocol howto:
48 Shematic of cable for RTS/CTS protocol (B. Torok - Jun. 2000)
50 <- DB9 female connector -><- RS232 driver/receiver -><- 8051 system ->
51 connect to PC e.g. MAX232
58 Transmitters/Receivers
60 Pin2-----------------------------<<<-------------------TXD
63 Pin3----------------------------->>>-------------------RXD
66 Pin5---------------------------------------------------GND
69 Pin6---Pin8----------------------<<<-------------------CTS (see #define CTS)
72 Pin7----------------------------->>>-------------------RTS (see #define RTS)
80 #define RXBUFLEN 18 // The minimum rx buffer size for safe communications
81 // is 17. (The UART in the PC has a 16-byte FIFO.)
82 // TXBUFLEN & RXBUFLEN can be highher if rxbuf[] and txbuf[] is in xdata, max size is limited to 256!
88 #define CTS P3_6 // CTS & RTS can be assigned to any free pins
91 static unsigned char rxbuf[RXBUFLEN], txbuf[TXBUFLEN];
92 static unsigned char rxcnt, txcnt, rxpos, txpos;
93 static unsigned char busy;
98 rxcnt = txcnt = rxpos = txpos = 0; // init buffers
100 SCON = 0x50; // mode 1 - 8-bit UART
101 PCON |= 0x80; // SMOD = 1;
102 TMOD &= 0x0f; // use timer 1
104 // TL1 = TH1 = 256 - 104; // 600bps with 12 MHz crystal
105 // TL1 = TH1 = 256 - 52; // 1200bps with 12 MHz crystal
106 // TL1 = TH1 = 256 - 26; // 2400bps with 12 MHz crystal
107 TL1 = TH1 = 256 - 13; // 4800bps with 12 MHz crystal
109 TR1 = 1; // Enable timer 1
115 void ser_handler(void) interrupt 4
119 /* don't overwrite chars already in buffer */
120 if(rxcnt < RXBUFLEN) rxbuf [(rxpos + rxcnt++) % RXBUFLEN] = SBUF;
121 if(rxcnt >= (RXBUFLEN - THRESHOLD)) CTS = DISABLE;
126 if (busy = txcnt) { /* Assignment, _not_ comparison! */
128 SBUF = txbuf[txpos++];
129 if(txpos >= TXBUFLEN) txpos = 0;
134 void ser_putc(unsigned char c)
136 while(txcnt >= TXBUFLEN); // wait for room in buffer
138 while(RTS == DISABLE);
142 txbuf[(txpos + txcnt++) % TXBUFLEN] = c;
150 unsigned char ser_getc(void)
154 while (!rxcnt) { // wait for a character
161 if (rxpos >= RXBUFLEN) rxpos = 0;
168 void ser_puts(unsigned char *s)
172 if (c == '\n') ser_putc('\r');
178 void ser_gets(unsigned char *s, unsigned char len)
180 unsigned char pos, c;
185 if (c == '\r') continue; // discard CR's
187 if (c == '\n') break; // NL terminates
189 s[pos] = '\0'; // terminate string
192 unsigned char ser_can_xmt(void)
194 return TXBUFLEN - txcnt;
197 unsigned char ser_can_rcv(void)