OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [powerpc/] [ppc403/] [console/] [console.c] - Blame information for rev 607

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *  This file contains the PowerPC 403GA console IO package.
3
 *
4
 *  Author:     Thomas Doerfler <td@imd.m.isar.de>
5
 *              IMD Ingenieurbuero fuer Microcomputertechnik
6
 *
7
 *  COPYRIGHT (c) 1998 by IMD
8
 *
9
 *  Changes from IMD are covered by the original distributions terms.
10
 *  changes include interrupt support and termios support
11
 *  for backward compatibility, the original polled driver has been
12
 *  renamed to console.c.polled
13
 *
14
 *  This file has been initially created (polled version) by
15
 *
16
 *  Author:     Andrew Bray <andy@i-cubed.co.uk>
17
 *
18
 *  COPYRIGHT (c) 1995 by i-cubed ltd.
19
 *
20
 *  To anyone who acknowledges that this file is provided "AS IS"
21
 *  without any express or implied warranty:
22
 *      permission to use, copy, modify, and distribute this file
23
 *      for any purpose is hereby granted without fee, provided that
24
 *      the above copyright notice and this notice appears in all
25
 *      copies, and that the name of i-cubed limited not be used in
26
 *      advertising or publicity pertaining to distribution of the
27
 *      software without specific, written prior permission.
28
 *      i-cubed limited makes no representations about the suitability
29
 *      of this software for any purpose.
30
 *
31
 *  Modifications for spooling (interrupt driven) console driver
32
 *            by Thomas Doerfler <td@imd.m.isar.de>
33
 *  for these modifications:
34
 *  COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.
35
 *
36
 *  To anyone who acknowledges that this file is provided "AS IS"
37
 *  without any express or implied warranty:
38
 *      permission to use, copy, modify, and distribute this file
39
 *      for any purpose is hereby granted without fee, provided that
40
 *      the above copyright notice and this notice appears in all
41
 *      copies. IMD makes no representations about the suitability
42
 *      of this software for any purpose.
43
 *
44
 *  Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
45
 *
46
 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
47
 *  On-Line Applications Research Corporation (OAR).
48
 *  All rights assigned to U.S. Government, 1994.
49
 *
50
 *  This material may be reproduced by or for the U.S. Government pursuant
51
 *  to the copyright license under the clause at DFARS 252.227-7013.  This
52
 *  notice must appear in all copies of this file and its derivatives.
53
 *
54
 *  console.c,v 1.4 1995/12/05 19:23:02 joel Exp
55
 */
56
 
57
#define NO_BSP_INIT
58
 
59
#include <rtems.h>
60
#include <rtems/libio.h>
61
#include "../ictrl/ictrl.h"
62
#include <stdlib.h>                                     /* for atexit() */
63
 
64
struct async {
65
/*---------------------------------------------------------------------------+
66
| Line Status Register.
67
+---------------------------------------------------------------------------*/
68
  unsigned char SPLS;
69
  unsigned char SPLSset;
70
#define LSRDataReady             0x80
71
#define LSRFramingError          0x40
72
#define LSROverrunError          0x20
73
#define LSRParityError           0x10
74
#define LSRBreakInterrupt        0x08
75
#define LSRTxHoldEmpty           0x04
76
#define LSRTxShiftEmpty          0x02
77
 
78
/*---------------------------------------------------------------------------+
79
| Handshake Status Register.
80
+---------------------------------------------------------------------------*/
81
  unsigned char SPHS;
82
  unsigned char SPHSset;
83
#define HSRDsr                   0x80
84
#define HSRCts                   0x40
85
 
86
/*---------------------------------------------------------------------------+
87
| Baud rate divisor registers
88
+---------------------------------------------------------------------------*/
89
  unsigned char BRDH;
90
  unsigned char BRDL;
91
 
92
/*---------------------------------------------------------------------------+
93
| Control Register.
94
+---------------------------------------------------------------------------*/
95
  unsigned char SPCTL;
96
#define CRNormal                 0x00
97
#define CRLoopback               0x40
98
#define CRAutoEcho               0x80
99
#define CRDtr                    0x20
100
#define CRRts                    0x10
101
#define CRWordLength7            0x00
102
#define CRWordLength8            0x08
103
#define CRParityDisable          0x00
104
#define CRParityEnable           0x04
105
#define CREvenParity             0x00
106
#define CROddParity              0x02
107
#define CRStopBitsOne            0x00
108
#define CRStopBitsTwo            0x01
109
#define CRDisableDtrRts          0x00
110
 
111
/*--------------------------------------------------------------------------+
112
| Receiver Command Register.
113
+--------------------------------------------------------------------------*/
114
  unsigned char SPRC;
115
#define RCRDisable               0x00
116
#define RCREnable                0x80
117
#define RCRIntDisable            0x00
118
#define RCRIntEnabled            0x20
119
#define RCRDMACh2                0x40
120
#define RCRDMACh3                0x60
121
#define RCRErrorInt              0x10
122
#define RCRPauseEnable           0x08
123
 
124
/*--------------------------------------------------------------------------+
125
| Transmitter Command Register.
126
+--------------------------------------------------------------------------*/
127
    unsigned char SPTC;
128
#define TCRDisable               0x00
129
#define TCREnable                0x80
130
#define TCRIntDisable            0x00
131
#define TCRIntEnabled            0x20
132
#define TCRDMACh2                0x40
133
#define TCRDMACh3                0x60
134
#define TCRTxEmpty               0x10
135
#define TCRErrorInt              0x08
136
#define TCRStopPause             0x04
137
#define TCRBreakGen              0x02
138
 
139
/*--------------------------------------------------------------------------+
140
| Miscellanies defines.
141
+--------------------------------------------------------------------------*/
142
  unsigned char SPTB;
143
#define SPRB    SPTB
144
};
145
 
146
typedef volatile struct async *pasync;
147
static const pasync port = (pasync)0x40000000;
148
 
149
static void *spittyp;         /* handle for termios */
150
int ppc403_spi_interrupt = 1; /* do not use interrupts... */
151
 
152
/*
153
 * Rx Interrupt handler
154
 */
155
static rtems_isr
156
spiRxInterruptHandler (rtems_vector_number v)
157
{
158
  char ch;
159
 
160
  /* clear any receive errors (errors are ignored now) */
161
  port->SPLS = (LSRFramingError | LSROverrunError |
162
                LSRParityError  | LSRBreakInterrupt);
163
  /*
164
   * Buffer received?
165
   */
166
  if (port->SPLS & LSRDataReady) {
167
    ch = port->SPRB; /* read receive buffer */
168
    rtems_termios_enqueue_raw_characters (spittyp,&ch,1);
169
  }
170
}
171
 
172
/*
173
 * Tx Interrupt handler
174
 */
175
static rtems_isr
176
spiTxInterruptHandler (rtems_vector_number v)
177
{
178
  /*
179
   * char transmitted?
180
   */
181
  if (0 != (port->SPLS & LSRTxHoldEmpty)) { /* must always be true!! */
182
    port->SPTC &= ~TCRIntEnabled;           /* stop irqs for now...  */
183
                                            /* and call termios...   */
184
    rtems_termios_dequeue_characters (spittyp,1);
185
  }
186
}
187
 
188
/*
189
 * enable/disable RTS line to start/stop remote transmitter
190
 */
191
static int
192
spiStartRemoteTx (int minor)
193
{
194
  rtems_interrupt_level level;
195
 
196
  rtems_interrupt_disable (level);
197
  port->SPCTL |= CRRts;           /* activate RTS  */
198
  rtems_interrupt_enable (level);
199
  return 0;
200
}
201
 
202
static int
203
spiStopRemoteTx (int minor)
204
{
205
  rtems_interrupt_level level;
206
 
207
  rtems_interrupt_disable (level);
208
  port->SPCTL &= ~CRRts;           /* deactivate RTS  */
209
  rtems_interrupt_enable (level);
210
  return 0;
211
}
212
 
213
void
214
spiBaudSet(unsigned32 baudrate)
215
{
216
  unsigned32 tmp;
217
  tmp = rtems_cpu_configuration_get_serial_per_sec() / baudrate;
218
  tmp = ((tmp) >> 4) - 1;
219
  port->BRDL = tmp & 0xff;
220
  port->BRDH = tmp >> 8;
221
 
222
}
223
/*
224
 * Hardware-dependent portion of tcsetattr().
225
 */
226
static int
227
spiSetAttributes (int minor, const struct termios *t)
228
{
229
  int baud;
230
 
231
  /* FIXME: check c_cflag & CRTSCTS for hardware flowcontrol */
232
  /* FIXME: check and IMPLEMENT XON/XOFF                     */
233
  switch (t->c_cflag & CBAUD) {
234
  default:      baud = -1;      break;
235
  case B50:     baud = 50;      break;
236
  case B75:     baud = 75;      break;
237
  case B110:    baud = 110;     break;
238
  case B134:    baud = 134;     break;
239
  case B150:    baud = 150;     break;
240
  case B200:    baud = 200;     break;
241
  case B300:    baud = 300;     break;
242
  case B600:    baud = 600;     break;
243
  case B1200:   baud = 1200;    break;
244
  case B1800:   baud = 1800;    break;
245
  case B2400:   baud = 2400;    break;
246
  case B4800:   baud = 4800;    break;
247
  case B9600:   baud = 9600;    break;
248
  case B19200:  baud = 19200;   break;
249
  case B38400:  baud = 38400;   break;
250
  case B57600:  baud = 57600;   break;
251
  case B115200: baud = 115200;  break;
252
  case B230400: baud = 230400;  break;
253
  case B460800: baud = 460800;  break;
254
  }
255
  if (baud > 0) {
256
    spiBaudSet(baud);
257
  }
258
  return 0;
259
}
260
 
261
static int
262
spiPollRead (int minor)
263
{
264
  unsigned char status;
265
 
266
  while (0 == ((status = port->SPLS) & LSRDataReady)) {
267
    /* Clean any dodgy status */
268
    if ((status & (LSRFramingError | LSROverrunError | LSRParityError |
269
                   LSRBreakInterrupt)) != 0) {
270
      port->SPLS = (LSRFramingError | LSROverrunError | LSRParityError |
271
                    LSRBreakInterrupt);
272
    }
273
  }
274
  return port->SPRB;
275
}
276
 
277
static int
278
spiInterruptWrite (int minor, const char *buf, int len)
279
{
280
  port->SPTB = *buf;           /* write char to send         */
281
  port->SPTC |= TCRIntEnabled; /* always enable tx interrupt */
282
  return 0;
283
}
284
 
285
static int
286
spiPollWrite(int minor,const char *buf,int len)
287
{
288
  unsigned char status;
289
 
290
  while (len-- > 0) {
291
    do {
292
      if (port->SPHS) {
293
        port->SPHS = (HSRDsr | HSRCts);
294
      }
295
      status = port->SPLS;
296
    } while (0 == (status & LSRTxHoldEmpty));
297
    port->SPTB = *buf++;
298
  }
299
  return 0;
300
}
301
 
302
/*
303
 *
304
 * deinit SPI
305
 *
306
 */
307
void
308
spiDeInit(void)
309
{
310
  /*
311
   * disable interrupts for serial port
312
   * set it to state to work with polling boot monitor, if any...
313
   */
314
 
315
  /* set up baud rate to original state */
316
  spiBaudSet(rtems_cpu_configuration_get_serial_rate());
317
 
318
  /* clear any receive (error) status */
319
  port->SPLS = (LSRDataReady   | LSRFramingError | LSROverrunError |
320
                LSRParityError | LSRBreakInterrupt);
321
 
322
  /* set up port control: DTR/RTS active,8 bit,1 stop,no parity */
323
  port->SPCTL = (CRNormal |
324
                 CRDtr | CRRts |
325
                 CRWordLength8 | CRParityDisable | CRStopBitsOne);
326
 
327
  /* clear handshake status bits */
328
  port->SPHS = (HSRDsr | HSRCts);
329
 
330
  /* enable receiver/transmitter, no interrupts */
331
  port->SPRC = (RCREnable | RCRIntDisable);
332
  port->SPTC = (TCREnable | TCRIntDisable);
333
 
334
}
335
 
336
/*
337
 *
338
 * init SPI
339
 *
340
 */
341
rtems_status_code
342
spiInitialize(void)
343
{
344
  register unsigned tmp;
345
  rtems_isr_entry previous_isr; /* this is a dummy */
346
 
347
  /*
348
   * Initialise the serial port
349
   */
350
 
351
  /*
352
   * select RTS/CTS hardware handshake lines,
353
   * select clock source
354
   */
355
  asm volatile ("mfdcr %0, 0xa0" : "=r" (tmp)); /* IOCR */
356
 
357
  tmp &= ~3;
358
  tmp |= (rtems_cpu_configuration_get_serial_external_clock() ? 2 : 0) | 1;
359
 
360
  asm volatile ("mtdcr 0xa0, %0" : "=r" (tmp) : "0" (tmp)); /* IOCR */
361
 
362
  /* clear any receive (error) status */
363
  port->SPLS = (LSRDataReady   | LSRFramingError | LSROverrunError |
364
                LSRParityError | LSRBreakInterrupt);
365
 
366
  /* set up baud rate */
367
  spiBaudSet(rtems_cpu_configuration_get_serial_rate());
368
 
369
  /* set up port control: DTR/RTS active,8 bit,1 stop,no parity */
370
  port->SPCTL = (CRNormal |
371
                 CRDtr | CRRts |
372
                 CRWordLength8 | CRParityDisable | CRStopBitsOne);
373
 
374
  /* clear handshake status bits */
375
  port->SPHS = (HSRDsr | HSRCts);
376
 
377
  if (ppc403_spi_interrupt) {
378
    /* add rx/tx isr to vector table */
379
    ictrl_set_vector(spiRxInterruptHandler,
380
                     PPC_IRQ_EXT_SPIR,
381
                     &previous_isr);
382
 
383
    ictrl_set_vector(spiTxInterruptHandler,
384
                     PPC_IRQ_EXT_SPIT,
385
                     &previous_isr);
386
 
387
    port->SPRC = (RCREnable | RCRIntEnabled | RCRErrorInt);
388
    port->SPTC = (TCREnable | TCRIntDisable); /* don't enable TxInt yet */
389
  }
390
  else {
391
    /* enable receiver/transmitter, no interrupts */
392
    port->SPRC = (RCREnable | RCRIntDisable);
393
    port->SPTC = (TCREnable | TCRIntDisable);
394
  }
395
 
396
  atexit(spiDeInit);
397
 
398
  return RTEMS_SUCCESSFUL;
399
}
400
 
401
/*
402
 ***************
403
 * BOILERPLATE *
404
 ***************
405
 */
406
 
407
/*  console_initialize
408
 *
409
 *  This routine initializes the console IO driver.
410
 *
411
 *  Input parameters: NONE
412
 *
413
 *  Output parameters:  NONE
414
 *
415
 *  Return values:
416
 */
417
 
418
rtems_device_driver console_initialize(
419
  rtems_device_major_number  major,
420
  rtems_device_minor_number  minor,
421
  void                      *arg
422
)
423
{
424
  rtems_status_code status;
425
 
426
  /*
427
   * Set up TERMIOS
428
   */
429
  rtems_termios_initialize ();
430
 
431
  /*
432
   * Do device-specific initialization
433
   */
434
  spiInitialize ();
435
 
436
  /*
437
   * Register the device
438
   */
439
  status = rtems_io_register_name ("/dev/console", major, 0);
440
  if (status != RTEMS_SUCCESSFUL)
441
    rtems_fatal_error_occurred (status);
442
  return RTEMS_SUCCESSFUL;
443
}
444
 
445
 
446
/*
447
 *  Open entry point
448
 */
449
 
450
rtems_device_driver console_open(
451
  rtems_device_major_number major,
452
  rtems_device_minor_number minor,
453
  void                    * arg
454
)
455
{
456
  rtems_status_code sc;
457
  static const rtems_termios_callbacks intrCallbacks = {
458
    NULL,               /* firstOpen */
459
    NULL,               /* lastClose */
460
    NULL,               /* pollRead */
461
    spiInterruptWrite,  /* write */
462
    spiSetAttributes,   /* setAttributes */
463
    spiStopRemoteTx,    /* stopRemoteTx */
464
    spiStartRemoteTx,   /* startRemoteTx */
465
    1                   /* outputUsesInterrupts */
466
  };
467
 
468
  static const rtems_termios_callbacks pollCallbacks = {
469
    NULL,               /* firstOpen */
470
    NULL,               /* lastClose */
471
    spiPollRead,        /* pollRead */
472
    spiPollWrite,       /* write */
473
    spiSetAttributes,   /* setAttributes */
474
    spiStopRemoteTx,    /* stopRemoteTx */
475
    spiStartRemoteTx,   /* startRemoteTx */
476
 
477
  };
478
 
479
  if (ppc403_spi_interrupt) {
480
    rtems_libio_open_close_args_t *args = arg;
481
 
482
    sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
483
    spittyp = args->iop->data1;
484
  }
485
  else {
486
    sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
487
  }
488
  return sc;
489
}
490
 
491
/*
492
 *  Close entry point
493
 */
494
 
495
rtems_device_driver console_close(
496
  rtems_device_major_number major,
497
  rtems_device_minor_number minor,
498
  void                    * arg
499
)
500
{
501
  return rtems_termios_close (arg);
502
}
503
 
504
/*
505
 * read bytes from the serial port. We only have stdin.
506
 */
507
 
508
rtems_device_driver console_read(
509
  rtems_device_major_number major,
510
  rtems_device_minor_number minor,
511
  void                    * arg
512
)
513
{
514
  return rtems_termios_read (arg);
515
}
516
 
517
/*
518
 * write bytes to the serial port. Stdout and stderr are the same.
519
 */
520
 
521
rtems_device_driver console_write(
522
  rtems_device_major_number major,
523
  rtems_device_minor_number minor,
524
  void                    * arg
525
)
526
{
527
  return rtems_termios_write (arg);
528
}
529
 
530
/*
531
 *  IO Control entry point
532
 */
533
 
534
rtems_device_driver console_control(
535
  rtems_device_major_number major,
536
  rtems_device_minor_number minor,
537
  void                    * arg
538
)
539
{
540
  return rtems_termios_ioctl (arg);
541
}
542
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.