source: rtems/c/src/lib/libcpu/powerpc/ppc403/console/console405.c @ 9b4422a2

4.11
Last change on this file since 9b4422a2 was 9b4422a2, checked in by Joel Sherrill <joel.sherrill@…>, on May 3, 2012 at 3:09:24 PM

Remove All CVS Id Strings Possible Using a Script

Script does what is expected and tries to do it as
smartly as possible.

+ remove occurrences of two blank comment lines

next to each other after Id string line removed.

+ remove entire comment blocks which only exited to

contain CVS Ids

+ If the processing left a blank line at the top of

a file, it was removed.

  • Property mode set to 100644
File size: 13.9 KB
Line 
1/*
2 *  This file contains the PowerPC 405GP 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 *
37 *  To anyone who acknowledges that this file is provided "AS IS"
38 *  without any express or implied warranty:
39 *      permission to use, copy, modify, and distribute this file
40 *      for any purpose is hereby granted without fee, provided that
41 *      the above copyright notice and this notice appears in all
42 *      copies. IMD makes no representations about the suitability
43 *      of this software for any purpose.
44 *
45 *  Derived from c/src/lib/libbsp/no_cpu/no_bsp/console/console.c:
46 *
47 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
48 *  On-Line Applications Research Corporation (OAR).
49 *
50 *  Modifications for PPC405GP by Dennis Ehlin
51 */
52
53#define NO_BSP_INIT
54
55#include <rtems.h>
56#include <rtems/libio.h>
57#include "../irq/ictrl.h"
58#include <stdlib.h>                                     /* for atexit() */
59
60
61
62struct async {
63/*---------------------------------------------------------------------------+
64| Data Register.
65+---------------------------------------------------------------------------*/
66  unsigned char RBR;    /* 0x00 */
67  #define THR   RBR
68/*---------------------------------------------------------------------------+
69| Interrupt registers
70+---------------------------------------------------------------------------*/
71  unsigned char IER;    /* 0x01 */
72  #define IER_RCV                0x01
73  #define IER_XMT                0x02
74  #define IER_LS                 0x04
75  #define IER_MS                 0x08
76
77  unsigned char ISR;    /* 0x02 */
78  #define ISR_MS                 0x00
79  #define ISR_nIP                0x01
80  #define ISR_Tx                 0x02
81  #define ISR_Rx                 0x04
82  #define ISR_LS                 0x06
83  #define ISR_RxTO               0x0C
84  #define ISR_64BFIFO            0x20
85  #define ISR_FIFOworks          0x40
86  #define ISR_FIFOen             0x80
87
88/*---------------------------------------------------------------------------+
89| FIFO Control registers
90+---------------------------------------------------------------------------*/
91  #define FCR   ISR
92  #define FCR_FE                0x01    /* FIFO enable */
93  #define FCR_CRF               0x02    /* Clear receive FIFO */
94  #define FCR_CTF               0x04    /* Clear transmit FIFO */
95  #define FCR_DMA               0x08    /* DMA mode select */
96  #define FCR_F64               0x20    /* Enable 64 byte fifo (16750+) */
97  #define FCR_RT14              0xC0    /* Set Rx trigger at 14 */
98  #define FCR_RT8               0x80    /* Set Rx trigger at 8 */
99  #define FCR_RT4               0x40    /* Set Rx trigger at 4 */
100  #define FCR_RT1               0x00    /* Set Rx trigger at 1 */
101
102/*---------------------------------------------------------------------------+
103| Baud rate divisor registers
104+---------------------------------------------------------------------------*/
105  #define DLL   RBR
106  #define DLM   IER
107
108/*---------------------------------------------------------------------------+
109| Alternate function registers
110+---------------------------------------------------------------------------*/
111  #define AFR   ISR
112
113/*---------------------------------------------------------------------------+
114| Line control Register.
115+---------------------------------------------------------------------------*/
116  unsigned char LCR;    /* 0x03 */
117  #define LCR_WL5                0x00   /* Word length 5 */
118  #define LCR_WL6                0x01   /* Word length 6 */
119  #define LCR_WL7                0x02   /* Word length 7 */
120  #define LCR_WL8                0x03   /* Word length 8 */
121
122  #define LCR_SB1                0x00   /* 1 stop bits */
123  #define LCR_SB1_5              0x04   /* 1.5 stop bits , only valid with 5 bit words*/
124  #define LCR_SB1_5              0x04   /* 2 stop bits */
125
126  #define LCR_PN                 0x00   /* Parity NONE */
127  #define LCR_PE                 0x0C   /* Parity EVEN */
128  #define LCR_PO                 0x08   /* Parity ODD */
129  #define LCR_PM                 0x28   /* Forced "mark" parity */
130  #define LCR_PS                 0x38   /* Forced "space" parity */
131
132  #define LCR_DL                 0x80   /* Enable baudrate latch */
133
134/*---------------------------------------------------------------------------+
135| Modem control Register.
136+---------------------------------------------------------------------------*/
137  unsigned char MCR;    /* 0x04 */
138  #define MCR_DTR                0x01
139  #define MCR_RTS                0x02
140  #define MCR_INT                0x08   /* Enable interrupts */
141  #define MCR_LOOP               0x10   /* Loopback mode */
142
143/*---------------------------------------------------------------------------+
144| Line status Register.
145+---------------------------------------------------------------------------*/
146  unsigned char LSR;    /* 0x05 */
147  #define LSR_RSR                0x01
148  #define LSR_OE                 0x02
149  #define LSR_PE                 0x04
150  #define LSR_FE                 0x08
151  #define LSR_BI                 0x10
152  #define LSR_THE                0x20
153  #define LSR_TEMT               0x40
154  #define LSR_FIE                0x80
155
156/*---------------------------------------------------------------------------+
157| Modem status Register.
158+---------------------------------------------------------------------------*/
159  unsigned char MSR;    /* 0x06 */
160  #define UART_MSR_DCTS          0x01
161  #define UART_MSR_DDSR          0x02
162  #define UART_MSR_TERI          0x04
163  #define UART_MSR_DDCD          0x08
164  #define UART_MSR_CTS           0x10
165  #define UART_MSR_DSR           0x20
166  #define UART_MSR_RI            0x40
167  #define UART_MSR_CD            0x80
168
169/*---------------------------------------------------------------------------+
170| Scratch pad Register.
171+---------------------------------------------------------------------------*/
172  unsigned char SCR;    /* 0x07 */
173};
174
175
176#define USE_UART 0 /* 0=UART0 1=UART1 */
177#define UART_INTERNAL_CLOCK_DIVISOR 16
178
179typedef volatile struct async *pasync;
180static const pasync port = (pasync)(0xEF600300   + (USE_UART*0x100));   /* 0xEF600300 - port A,  0xEF600400 - port B */
181
182static void *spittyp;         /* handle for termios */
183int ppc403_spi_interrupt = 0; /* do not use interrupts... */
184
185extern uint32_t bsp_serial_per_sec;
186extern uint32_t bsp_serial_rate;
187extern bool bsp_serial_external_clock;
188
189static int spiBaudRound(double x)
190{
191  return (int)((int)((x-(int)x)*1000)>500 ? x+1 : x);
192}
193
194void
195spiBaudSet(uint32_t   baudrate)
196{
197  uint32_t   tmp;
198
199  tmp = spiBaudRound( (double)bsp_serial_per_sec / (baudrate * 16) );
200
201  port->LCR = port->LCR | LCR_DL;
202
203  port->DLL = tmp & 0xff;
204  port->DLM = tmp >> 8;
205
206  port->LCR = port->LCR & ~LCR_DL;
207}
208/*
209 * Hardware-dependent portion of tcsetattr().
210 */
211static int
212spiSetAttributes (int minor, const struct termios *t)
213{
214  int baud;
215
216  /* FIXME: check c_cflag & CRTSCTS for hardware flowcontrol */
217  /* FIXME: check and IMPLEMENT XON/XOFF                     */
218  switch (t->c_cflag & CBAUD) {
219  default:      baud = -1;      break;
220  case B50:     baud = 50;      break;
221  case B75:     baud = 75;      break;
222  case B110:    baud = 110;     break;
223  case B134:    baud = 134;     break;
224  case B150:    baud = 150;     break;
225  case B200:    baud = 200;     break;
226  case B300:    baud = 300;     break;
227  case B600:    baud = 600;     break;
228  case B1200:   baud = 1200;    break;
229  case B1800:   baud = 1800;    break;
230  case B2400:   baud = 2400;    break;
231  case B4800:   baud = 4800;    break;
232  case B9600:   baud = 9600;    break;
233  case B19200:  baud = 19200;   break;
234  case B38400:  baud = 38400;   break;
235  case B57600:  baud = 57600;   break;
236  case B115200: baud = 115200;  break;
237  case B230400: baud = 230400;  break;
238  case B460800: baud = 460800;  break;
239  }
240  if (baud > 0) {
241    spiBaudSet(baud);
242  }
243  return 0;
244}
245
246static int
247spiPollRead (int minor)
248{
249
250  /* Wait for character */
251  while ((port->LSR & LSR_RSR)==0);;
252
253  return port->RBR;
254}
255
256
257static ssize_t
258spiPollWrite(int minor, const char *buf, size_t len)
259{
260
261  while (len-- > 0) {
262    while (!(port->LSR & LSR_THE));;
263    port->THR = *buf++;
264  }
265  return 0;
266}
267
268/*
269 * enable/disable RTS line to start/stop remote transmitter
270 */
271static int
272spiStartRemoteTx (int minor)
273{
274/* Not implemented !
275  rtems_interrupt_level level;
276
277  rtems_interrupt_disable (level);
278  port->SPCTL |= CRRts;            activate RTS
279  rtems_interrupt_enable (level);
280*/
281  return 0;
282}
283
284static int
285spiStopRemoteTx (int minor)
286{
287/* Not implemented !
288  rtems_interrupt_level level;
289
290  rtems_interrupt_disable (level);
291  port->SPCTL &= ~CRRts;            deactivate RTS
292  rtems_interrupt_enable (level);
293*/
294  return 0;
295}
296
297static ssize_t InterruptWrite (int minor, const char *buf, size_t len)
298{
299  port->IER |= IER_XMT;     /* always enable tx interrupt */
300  port->THR = *buf;         /* write char to send         */
301  return 0;
302}
303
304static rtems_isr serial_ISR(rtems_vector_number v)
305{
306  unsigned char _isr;
307  char ch;
308  int res;
309
310  _isr=port->ISR & 0x0E;
311
312   if ((_isr == ISR_Rx) || (_isr==ISR_RxTO)) {
313        ch = port->RBR;
314        rtems_termios_enqueue_raw_characters (spittyp,&ch,1);
315   }
316
317   if (_isr == ISR_Tx) {
318        res = rtems_termios_dequeue_characters (spittyp,1);
319        if (res==0) {
320                port->IER &= ~IER_XMT;
321                }
322
323   }
324}
325
326
327/*
328 *
329 * deinit SPI
330 *
331 */
332void
333spiDeInit(void)
334{
335  /*
336   * disable interrupts for serial port
337   * set it to state to work with polling boot monitor, if any...
338   */
339
340
341  /* set up baud rate to original state */
342  spiBaudSet(bsp_serial_rate);
343
344  port->IER = 0;
345
346}
347
348/*
349 *
350 * init SPI
351 *
352 */
353rtems_status_code
354spiInitialize(void)
355{
356  register unsigned tmp;
357  rtems_isr_entry previous_isr; /* this is a dummy */
358  unsigned char _ier;
359
360  /*
361   * Initialise the serial port
362   */
363
364  /*
365   * Select clock source and set uart internal clock divisor
366   */
367
368  __asm__ volatile ("mfdcr %0, 0x0b1" : "=r" (tmp)); /* CPC_CR0 0x0b1 */
369
370  /* UART0 bit 24 0x80, UART1 bit 25 0x40 */
371  tmp |= (bsp_serial_external_clock ?  (USE_UART ? 0x40 : 0x80) : 0);
372
373  tmp |= (bsp_serial_external_clock ?  0: ((UART_INTERNAL_CLOCK_DIVISOR -1) << 1));
374
375  __asm__ volatile ("mtdcr 0x0b1, %0" : "=r" (tmp) : "0" (tmp)); /* CPC_CR0 0x0b1*/
376
377  /* Disable port interrupts while changing hardware */
378  _ier = port->IER;
379  port->IER = 0;
380
381  /* set up port control: 8 bit,1 stop,no parity */
382  port->LCR = LCR_WL8 | LCR_SB1 | LCR_PN;
383
384  /* set up baud rate */
385  spiBaudSet(bsp_serial_rate);
386
387  if (ppc403_spi_interrupt) {
388
389    /* add rx/tx isr to vector table */
390    if (USE_UART==0)
391        ictrl_set_vector(serial_ISR,PPC_IRQ_EXT_UART0,&previous_isr);
392    else
393        ictrl_set_vector(serial_ISR,PPC_IRQ_EXT_UART1,&previous_isr);
394
395    /* Enable and clear FIFO */
396    port->FCR = FCR_FE | FCR_CRF | FCR_CTF | FCR_RT8;
397
398    /* Enable recive interrupts, don't enable TxInt yet */
399    port->IER=IER_RCV;
400  }
401  else {
402    port->IER=_ier;
403  }
404
405  atexit(spiDeInit);
406
407  return RTEMS_SUCCESSFUL;
408}
409
410/*
411 ***************
412 * BOILERPLATE *
413 ***************
414 */
415
416/*  console_initialize
417 *
418 *  This routine initializes the console IO driver.
419 *
420 *  Input parameters: NONE
421 *
422 *  Output parameters:  NONE
423 *
424 *  Return values:
425 */
426
427rtems_device_driver console_initialize(
428  rtems_device_major_number  major,
429  rtems_device_minor_number  minor,
430  void                      *arg
431)
432{
433  rtems_status_code status;
434
435  /*
436   * Set up TERMIOS
437   */
438  rtems_termios_initialize ();
439
440  /*
441   * Do device-specific initialization
442   */
443  spiInitialize ();
444
445  /*
446   * Register the device
447   */
448  status = rtems_io_register_name ("/dev/console", major, 0);
449  if (status != RTEMS_SUCCESSFUL)
450    rtems_fatal_error_occurred (status);
451  return RTEMS_SUCCESSFUL;
452}
453
454
455/*
456 *  Open entry point
457 */
458
459rtems_device_driver console_open(
460  rtems_device_major_number major,
461  rtems_device_minor_number minor,
462  void                    * arg
463)
464{
465  rtems_status_code sc;
466  static const rtems_termios_callbacks intrCallbacks = {
467    NULL,               /* firstOpen */
468    NULL,               /* lastClose */
469    NULL,               /* pollRead */
470    InterruptWrite,     /* write */
471    spiSetAttributes,   /* setAttributes */
472    spiStopRemoteTx,    /* stopRemoteTx */
473    spiStartRemoteTx,   /* startRemoteTx */
474    1                   /* outputUsesInterrupts */
475  };
476
477  static const rtems_termios_callbacks pollCallbacks = {
478    NULL,               /* firstOpen */
479    NULL,               /* lastClose */
480    spiPollRead,        /* pollRead */
481    spiPollWrite,       /* write */
482    spiSetAttributes,   /* setAttributes */
483    spiStopRemoteTx,    /* stopRemoteTx */
484    spiStartRemoteTx,   /* startRemoteTx */
485    0                   /* outputUsesInterrupts */
486  };
487
488  if (ppc403_spi_interrupt) {
489    rtems_libio_open_close_args_t *args = arg;
490    sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
491    spittyp = args->iop->data1;
492  }
493  else {
494    sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
495  }
496  return sc;
497}
498
499/*
500 *  Close entry point
501 */
502
503rtems_device_driver console_close(
504  rtems_device_major_number major,
505  rtems_device_minor_number minor,
506  void                    * arg
507)
508{
509  return rtems_termios_close (arg);
510}
511
512/*
513 * read bytes from the serial port. We only have stdin.
514 */
515
516rtems_device_driver console_read(
517  rtems_device_major_number major,
518  rtems_device_minor_number minor,
519  void                    * arg
520)
521{
522  return rtems_termios_read (arg);
523}
524
525/*
526 * write bytes to the serial port. Stdout and stderr are the same.
527 */
528
529rtems_device_driver console_write(
530  rtems_device_major_number major,
531  rtems_device_minor_number minor,
532  void                    * arg
533)
534{
535  return rtems_termios_write (arg);
536}
537
538/*
539 *  IO Control entry point
540 */
541
542rtems_device_driver console_control(
543  rtems_device_major_number major,
544  rtems_device_minor_number minor,
545  void                    * arg
546)
547{
548  return rtems_termios_ioctl (arg);
549}
Note: See TracBrowser for help on using the repository browser.