source: rtems/c/src/lib/libcpu/powerpc/ppc403/console/console.c @ e57b0e2

4.104.114.84.95
Last change on this file since e57b0e2 was e57b0e2, checked in by Joel Sherrill <joel.sherrill@…>, on Dec 5, 1995 at 7:23:05 PM

update from Andy Bray <andy@…>

  • Property mode set to 100644
File size: 9.5 KB
Line 
1/*
2 *  This file contains the PowerPC 403GA console IO package.
3 *
4 *  Author:     Andrew Bray <andy@i-cubed.co.uk>
5 *
6 *  COPYRIGHT (c) 1995 by i-cubed ltd.
7 *
8 *  To anyone who acknowledges that this file is provided "AS IS"
9 *  without any express or implied warranty:
10 *      permission to use, copy, modify, and distribute this file
11 *      for any purpose is hereby granted without fee, provided that
12 *      the above copyright notice and this notice appears in all
13 *      copies, and that the name of i-cubed limited not be used in
14 *      advertising or publicity pertaining to distribution of the
15 *      software without specific, written prior permission.
16 *      i-cubed limited makes no representations about the suitability
17 *      of this software for any purpose.
18 *
19 *  Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
20 *
21 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
22 *  On-Line Applications Research Corporation (OAR).
23 *  All rights assigned to U.S. Government, 1994.
24 *
25 *  This material may be reproduced by or for the U.S. Government pursuant
26 *  to the copyright license under the clause at DFARS 252.227-7013.  This
27 *  notice must appear in all copies of this file and its derivatives.
28 *
29 *  $Id$
30 */
31
32#define NO_BSP_INIT
33
34#include <bsp.h>
35#include <rtems/libio.h>
36
37extern rtems_cpu_table           Cpu_table;             /* owned by BSP */
38
39struct async {
40/*-----------------------------------------------------------------------------+
41| Line Status Register.
42+-----------------------------------------------------------------------------*/
43    unsigned char SPLS;
44    unsigned char SPLSset;
45#define LSRDataReady             0x80
46#define LSRFramingError          0x40
47#define LSROverrunError          0x20
48#define LSRParityError           0x10
49#define LSRBreakInterrupt        0x08
50#define LSRTxHoldEmpty           0x04
51#define LSRTxShiftEmpty          0x02
52
53/*-----------------------------------------------------------------------------+
54| Handshake Status Register.
55+-----------------------------------------------------------------------------*/
56    unsigned char SPHS;
57    unsigned char SPHSset;
58#define HSRDsr                   0x80
59#define HSRCts                   0x40
60
61/*-----------------------------------------------------------------------------+
62| Baud rate divisor registers
63+-----------------------------------------------------------------------------*/
64    unsigned char BRDH;
65    unsigned char BRDL;
66
67/*-----------------------------------------------------------------------------+
68| Control Register.
69+-----------------------------------------------------------------------------*/
70    unsigned char SPCTL;
71#define CRNormal                      0x00
72#define CRLoopback                    0x40
73#define CRAutoEcho                    0x80
74#define CRDtr                    0x20
75#define CRRts                    0x10
76#define CRWordLength7            0x00
77#define CRWordLength8            0x08
78#define CRParityDisable          0x00
79#define CRParityEnable           0x04
80#define CREvenParity             0x00
81#define CROddParity           0x02
82#define CRStopBitsOne            0x00
83#define CRStopBitsTwo            0x01
84#define CRDisableDtrRts       0x00
85
86/*-----------------------------------------------------------------------------+
87| Receiver Command Register.
88+-----------------------------------------------------------------------------*/
89    unsigned char SPRC;
90#define RCRDisable                    0x00
91#define RCREnable                     0x80
92#define RCRIntDisable         0x00
93#define RCRIntEnabled         0x20
94#define RCRDMACh2                     0x40
95#define RCRDMACh3                     0x60
96#define RCRErrorInt           0x10
97#define RCRPauseEnable        0x08
98
99/*-----------------------------------------------------------------------------+
100| Transmitter Command Register.
101+-----------------------------------------------------------------------------*/
102    unsigned char SPTC;
103#define TCRDisable                    0x00
104#define TCREnable                     0x80
105#define TCRIntDisable         0x00
106#define TCRIntEnabled         0x20
107#define TCRDMACh2                     0x40
108#define TCRDMACh3                     0x60
109#define TCRTxEmpty                    0x10
110#define TCRErrorInt           0x08
111#define TCRStopPause          0x04
112#define TCRBreakGen           0x02
113
114/*-----------------------------------------------------------------------------+
115| Miscellanies defines.
116+-----------------------------------------------------------------------------*/
117    unsigned char SPTB;
118#define SPRB    SPTB
119};
120
121#define XOFFchar                      0x13
122#define XONchar                       0x11
123
124typedef volatile struct async *pasync;
125static const pasync port = (pasync)0x40000000;
126
127/*  console_initialize
128 *
129 *  This routine initializes the console IO driver.
130 *
131 *  Input parameters: NONE
132 *
133 *  Output parameters:  NONE
134 *
135 *  Return values:
136 */
137
138rtems_device_driver console_initialize(
139  rtems_device_major_number  major,
140  rtems_device_minor_number  minor,
141  void                      *arg
142)
143{
144  rtems_status_code status;
145  register unsigned tmp;
146
147  /* Initialise the serial port */
148  asm volatile ("mfdcr %0, 0xa0" : "=r" (tmp)); /* IOCR */
149  tmp &= ~3;
150  tmp |= (Cpu_table.serial_external_clock ? 2 : 0) |
151      (Cpu_table.serial_cts_rts ? 1 : 0);
152  asm volatile ("mtdcr 0xa0, %0" : "=r" (tmp) : "0" (tmp)); /* IOCR */
153  port->SPLS = (LSRDataReady | LSRFramingError | LSROverrunError |
154         LSRParityError | LSRBreakInterrupt);
155  tmp = Cpu_table.serial_per_sec / Cpu_table.serial_rate;
156  tmp = ((tmp + 8) >> 4) - 1;
157  port->BRDL = tmp & 0x255;
158  port->BRDH = tmp >> 8;
159  port->SPCTL = (CRNormal | CRDtr | CRRts | CRWordLength8 | CRParityDisable |
160     CRStopBitsOne);
161  port->SPRC = (RCREnable | RCRIntDisable | RCRPauseEnable);
162  port->SPTC = (TCREnable | TCRIntDisable);
163  port->SPHS = (HSRDsr | HSRCts);
164
165  status = rtems_io_register_name(
166    "/dev/console",
167    major,
168    (rtems_device_minor_number) 0
169  );
170 
171  if (status != RTEMS_SUCCESSFUL)
172    rtems_fatal_error_occurred(status);
173 
174  return RTEMS_SUCCESSFUL;
175}
176
177
178/*  is_character_ready
179 *
180 *  This routine returns TRUE if a character is available.
181 *
182 *  Input parameters: NONE
183 *
184 *  Output parameters:  NONE
185 *
186 *  Return values:
187 */
188
189rtems_boolean is_character_ready(
190  char *ch
191)
192{
193  unsigned char status;
194
195  if ((status = port->SPLS) & LSRDataReady)
196    {
197      *ch = port->SPRB; 
198      return(TRUE);
199    }
200
201  /* Clean any dodgy status */
202  if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
203                 LSRBreakInterrupt)) != 0)
204    {
205      port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
206                 LSRBreakInterrupt);
207    }
208
209  return FALSE;
210}
211
212/*  inbyte
213 *
214 *  This routine reads a character from the SOURCE.
215 *
216 *  Input parameters: NONE
217 *
218 *  Output parameters:  NONE
219 *
220 *  Return values:
221 *    character read from SOURCE
222 */
223
224char inbyte( void )
225{
226  unsigned char status;
227
228  while (1)
229    {
230      if ((status = port->SPLS) & LSRDataReady)
231              break;
232
233      /* Clean any dodgy status */
234      if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
235                     LSRBreakInterrupt)) != 0)
236            {
237              port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
238                            LSRBreakInterrupt);
239            }
240    }
241
242  return port->SPRB; 
243}
244
245/*  outbyte
246 *
247 *  This routine transmits a character out the SOURCE.  It may support
248 *  XON/XOFF flow control.
249 *
250 *  Input parameters:
251 *    ch  - character to be transmitted
252 *
253 *  Output parameters:  NONE
254 */
255
256void outbyte(
257  char ch
258)
259{
260  unsigned char status;
261
262  while (port->SPHS)
263    port->SPHS = (HSRDsr | HSRCts);
264
265  while (1)
266    {
267      status = port->SPLS;
268
269      if (port->SPHS)
270        port->SPHS = (HSRDsr | HSRCts);
271      else if (status & LSRTxHoldEmpty)
272              break;
273    }
274
275  if (Cpu_table.serial_xon_xoff)
276    while (is_character_ready(&status))
277    {
278            if (status == XOFFchar)
279              do {
280                while (!is_character_ready(&status));
281              } while (status != XONchar);
282    }
283
284  port->SPTB = ch;
285}
286
287/*
288 *  Open entry point
289 */
290 
291rtems_device_driver console_open(
292  rtems_device_major_number major,
293  rtems_device_minor_number minor,
294  void                    * arg
295)
296{
297  return RTEMS_SUCCESSFUL;
298}
299 
300/*
301 *  Close entry point
302 */
303 
304rtems_device_driver console_close(
305  rtems_device_major_number major,
306  rtems_device_minor_number minor,
307  void                    * arg
308)
309{
310  return RTEMS_SUCCESSFUL;
311}
312 
313/*
314 * read bytes from the serial port. We only have stdin.
315 */
316 
317rtems_device_driver console_read(
318  rtems_device_major_number major,
319  rtems_device_minor_number minor,
320  void                    * arg
321)
322{
323  rtems_libio_rw_args_t *rw_args;
324  char *buffer;
325  int maximum;
326  int count = 0;
327 
328  rw_args = (rtems_libio_rw_args_t *) arg;
329 
330  buffer = rw_args->buffer;
331  maximum = rw_args->count;
332 
333  for (count = 0; count < maximum; count++) {
334    buffer[ count ] = inbyte();
335    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
336      buffer[ count++ ]  = '\n';
337      buffer[ count ]  = 0;
338      break;
339    }
340  }
341 
342  rw_args->bytes_moved = count;
343  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
344}
345 
346/*
347 * write bytes to the serial port. Stdout and stderr are the same.
348 */
349 
350rtems_device_driver console_write(
351  rtems_device_major_number major,
352  rtems_device_minor_number minor,
353  void                    * arg
354)
355{
356  int count;
357  int maximum;
358  rtems_libio_rw_args_t *rw_args;
359  char *buffer;
360 
361  rw_args = (rtems_libio_rw_args_t *) arg;
362 
363  buffer = rw_args->buffer;
364  maximum = rw_args->count;
365 
366  for (count = 0; count < maximum; count++) {
367    if ( buffer[ count ] == '\n') {
368      outbyte('\r');
369    }
370    outbyte( buffer[ count ] );
371  }
372  return maximum;
373}
374 
375/*
376 *  IO Control entry point
377 */
378 
379rtems_device_driver console_control(
380  rtems_device_major_number major,
381  rtems_device_minor_number minor,
382  void                    * arg
383)
384{
385  return RTEMS_SUCCESSFUL;
386}
387
Note: See TracBrowser for help on using the repository browser.