source: rtems/c/src/lib/libbsp/m68k/gen68302/console/console.c @ 8f35817

4.104.114.84.95
Last change on this file since 8f35817 was 8f35817, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 15, 1997 at 6:52:26 PM

eliminated potential for overfilling buffer on read

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2 * Initialize the MC68302 SCC2 for console IO board support package.
3 *
4 *  COPYRIGHT (c) 1989-1997.
5 *  On-Line Applications Research Corporation (OAR).
6 *  Copyright assigned to U.S. Government, 1994.
7 *
8 *  The license and distribution terms for this file may in
9 *  the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15#define GEN68302_INIT
16
17#include <bsp.h>
18#include <rtems/libio.h>
19
20#include "m68302.h"
21
22/*  console_initialize
23 *
24 *  This routine initializes the console IO driver.
25 *
26 *  Input parameters: NONE
27 *
28 *  Output parameters:  NONE
29 *
30 *  Return values:
31 */
32
33rtems_device_driver console_initialize(
34  rtems_device_major_number  major,
35  rtems_device_minor_number  minor,
36  void                      *arg
37)
38{
39  rtems_status_code status;
40  volatile m302_dualPortRAM_t *p = &m302;
41
42  p->reg.pacnt |= 0x0003;               /* enable RXD2 and TXD2 signals */
43  /*
44   * TODO: Check assembly code.  I think gcc's volatile semantics force
45   * this to not use a CLR.
46   */
47  p->reg.simode = 0;                    /* NMSI mode */
48
49  p->reg.scc[1].scon = 0x00d8;          /* 9600 baud */
50  p->reg.scc[1].scm  = 0x01b1;
51
52  p->scc2.parm.rfcr = 0x50;             /* Rx buffers in supervisor data */
53  p->scc2.parm.tfcr = 0x50;             /* Tx buffers in supervisor data */
54  p->scc2.parm.mrblr = 0x0001;          /* Max Rx buffer length is 1 byte */
55
56  p->scc2.prot.uart.max_idl = 0x0000;   /* 0 = maximum timeout value */
57  p->scc2.prot.uart.brkcr = 0x0001;     /* send 1 break char on STOP TX cmd */
58  p->scc2.prot.uart.parec = 0x0000;     /* reset parity error counter */
59  p->scc2.prot.uart.frmec = 0x0000;     /* reset framing error counter */
60  p->scc2.prot.uart.nosec = 0x0000;     /* reset noise error counter */
61  p->scc2.prot.uart.brkec = 0x0000;     /* reset break condition counter */
62
63  p->scc2.prot.uart.character[0] = 0x0003; /* use <ctrl>c as control char */
64  p->scc2.prot.uart.character[1] = 0x8000; /* set end of cntrl char table */
65
66  p->scc2.bd.rx[0].status = 0xA000;     /* RxBD0 empty, wrap, no intr */
67  p->scc2.bd.rx[0].length = 0x0000;
68  p->scc2.bd.rx[0].buffer =
69      (rtems_unsigned8 *) &m302.scc2.bd.rx[1]; /* RxBD1 is Rx buffer */
70
71  p->reg.scc[1].dsr = 0x7000;           /* set full-length last stop bit */
72
73  p->scc2.bd.tx[0].status = 0x3000;     /* TxBD0 not ready, wrap, intr */
74  p->scc2.bd.tx[0].length = 0x0001;
75  p->scc2.bd.tx[0].buffer =
76      (rtems_unsigned8 *) &m302.scc2.bd.tx[1]; /* TxBD1 is Tx buffer */
77
78  p->reg.scc[1].scce = 0xFF;            /* clear all SCC event flags */
79  p->reg.scc[1].sccm = 0x03;            /* enable only Tx & Rx interrupts */
80  p->reg.scc[1].scm  = 0x01BD;
81
82  status = rtems_io_register_name(
83    "/dev/console",
84    major,
85    (rtems_device_minor_number) 0
86  );
87 
88  if (status != RTEMS_SUCCESSFUL)
89    rtems_fatal_error_occurred(status);
90 
91  return RTEMS_SUCCESSFUL;
92
93}
94
95/*  is_character_ready
96 *
97 *  Check to see if a character is available on the MC68302's SCC2.  If so,
98 *  then return a TRUE (along with the character).  Otherwise return FALSE.
99 *
100 *  Input parameters:   pointer to location in which to return character
101 *
102 *  Output parameters:  character (if available)
103 *
104 *  Return values:      TRUE - character available
105 *                      FALSE - no character available
106 */
107
108rtems_boolean is_character_ready(
109  char *ch                              /* -> character  */
110)
111{
112#define RXS (m302.scc2.bd.rx[0].status)
113#define RXD (* ((volatile char *) m302.scc2.bd.rx[0].buffer))
114
115    for (;;) {
116        if (RXS & RBIT_HDLC_EMPTY_BIT)
117            return FALSE;
118
119        *ch = RXD;
120        RXS = RBIT_HDLC_EMPTY_BIT | RBIT_HDLC_WRAP_BIT;
121        if ( *ch >= ' ' &&  *ch <= '~' )
122            return TRUE;
123    }
124}
125
126
127/*  inbyte
128 *
129 *  Receive a character from the MC68302's SCC2.
130 *
131 *  Input parameters:   NONE
132 *
133 *  Output parameters:  NONE
134 *
135 *  Return values:      character read
136 */
137
138char inbyte( void )
139{
140    char ch;
141
142#define RXS (m302.scc2.bd.rx[0].status)
143#define RXD (* ((volatile char *) m302.scc2.bd.rx[0].buffer))
144
145    do {
146        while (RXS & RBIT_HDLC_EMPTY_BIT)
147            /* Wait until character received */ ;
148
149        ch = RXD;
150        RXS = RBIT_HDLC_EMPTY_BIT | RBIT_HDLC_WRAP_BIT;
151
152        if (ch == '\r' || ch == '\n')
153            break;
154    } while (ch < ' ' ||  ch > '~');
155
156    return ch;
157}
158
159
160/*  outbyte
161 *
162 *  Transmit a character out on the MC68302's SCC2.
163 *  It may support XON/XOFF flow control.
164 *
165 *  Input parameters:
166 *    ch  - character to be transmitted
167 *
168 *  Output parameters:  NONE
169 */
170
171void outbyte(
172  char ch
173)
174{
175#define TXS (m302.scc2.bd.tx[0].status)
176#define TXD (* ((volatile char *) m302.scc2.bd.tx[0].buffer))
177
178#define RXS (m302.scc2.bd.rx[0].status)
179#define RXD (* ((volatile char *) m302.scc2.bd.rx[0].buffer))
180
181    while (TXS & RBIT_HDLC_READY_BIT)
182        /* Wait until okay to transmit */ ;
183
184    /*
185     * Check for flow control requests and process.
186     */
187    while ( ! (RXS & RBIT_HDLC_EMPTY_BIT)) {
188        if (RXD == XOFF)
189            do {
190                RXS = RBIT_HDLC_EMPTY_BIT | RBIT_HDLC_WRAP_BIT;
191                while (RXS & RBIT_HDLC_EMPTY_BIT)
192                    /* Wait until character received */ ;
193            } while (RXD != XON);
194        RXS = RBIT_HDLC_EMPTY_BIT | RBIT_HDLC_WRAP_BIT;
195    }
196
197    TXD = ch;
198    TXS = RBIT_HDLC_READY_BIT | RBIT_HDLC_WRAP_BIT;
199    if (ch == '\n')
200        outbyte('\r');
201}
202
203/*
204 *  Open entry point
205 */
206
207rtems_device_driver console_open(
208  rtems_device_major_number major,
209  rtems_device_minor_number minor,
210  void                    * arg
211)
212{
213  return RTEMS_SUCCESSFUL;
214}
215 
216/*
217 *  Close entry point
218 */
219
220rtems_device_driver console_close(
221  rtems_device_major_number major,
222  rtems_device_minor_number minor,
223  void                    * arg
224)
225{
226  return RTEMS_SUCCESSFUL;
227}
228
229/*
230 * read bytes from the serial port. We only have stdin.
231 */
232
233rtems_device_driver console_read(
234  rtems_device_major_number major,
235  rtems_device_minor_number minor,
236  void                    * arg
237)
238{
239  rtems_libio_rw_args_t *rw_args;
240  char *buffer;
241  int maximum;
242  int count = 0;
243 
244  rw_args = (rtems_libio_rw_args_t *) arg;
245
246  buffer = rw_args->buffer;
247  maximum = rw_args->count;
248
249  for (count = 0; count < maximum; count++) {
250    buffer[ count ] = inbyte();
251    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
252      buffer[ count++ ]  = '\n';
253      break;
254    }
255  }
256
257  rw_args->bytes_moved = count;
258  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
259}
260
261/*
262 * write bytes to the serial port. Stdout and stderr are the same.
263 */
264
265rtems_device_driver console_write(
266  rtems_device_major_number major,
267  rtems_device_minor_number minor,
268  void                    * arg
269)
270{
271  int count;
272  int maximum;
273  rtems_libio_rw_args_t *rw_args;
274  char *buffer;
275
276  rw_args = (rtems_libio_rw_args_t *) arg;
277
278  buffer = rw_args->buffer;
279  maximum = rw_args->count;
280
281  for (count = 0; count < maximum; count++) {
282    if ( buffer[ count ] == '\n') {
283      outbyte('\r');
284    }
285    outbyte( buffer[ count ] );
286  }
287
288  rw_args->bytes_moved = maximum;
289  return 0;
290}
291
292/*
293 *  IO Control entry point
294 */
295
296rtems_device_driver console_control(
297  rtems_device_major_number major,
298  rtems_device_minor_number minor,
299  void                    * arg
300)
301{
302  return RTEMS_SUCCESSFUL;
303}
Note: See TracBrowser for help on using the repository browser.