source: rtems/c/src/lib/libbsp/or32/orp/console/console.c @ 35eb7632

4.104.114.84.95
Last change on this file since 35eb7632 was 35eb7632, checked in by Ralf Corsepius <ralf.corsepius@…>, on 03/31/04 at 04:22:15

2004-03-31 Ralf Corsepius <ralf_corsepius@…>

  • clock/clockdrv.c, console/console.c, startup/bspstart.c, timer/timer.c, timer/timerisr.c: Convert to using c99 fixed size types.
  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 *  This file contains the template for a console IO package.
3 *
4 *  COPYRIGHT (c) 1989-1999.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  This file adapted from no_bsp board library of the RTEMS distribution.
12 *  The body has been modified for the Bender Or1k implementation by
13 *  Chris Ziomkowski. <chris@asics.ws>
14 */
15
16#define BENDER_INIT
17
18#include <bsp.h>
19#include <rtems/libio.h>
20#include "console.h"
21
22static int localEcho;
23static UART_16450* uart = (UART_16450*)0x80000000;  /* This is where the simulator puts it */
24
25/*  console_initialize
26 *
27 *  This routine initializes the console IO driver.
28 *
29 *  Input parameters: NONE
30 *
31 *  Output parameters:  NONE
32 *
33 *  Return values:
34 */
35
36void (*old_handler)(unsigned int,unsigned int,unsigned int,unsigned int);
37
38void console_interrupt(unsigned int vector,unsigned int pc,
39                       unsigned int effective_addr, unsigned int status)
40{
41  int reason;
42  register int pending;
43
44  /* First thing's first...is this for us? */
45  asm volatile ("l.mfspr %0,r0,0x4802 \n\t"  /* Read the PIC status */
46                "l.andi  %0,%0,0x4    \n\t" : "=r" (pending));
47
48  if(pending)
49    {
50      reason = uart->read.IIR;
51     
52      switch(reason)
53        {
54        case 0: /* Interrupt because of modem status */
55          break;
56        case 2: /* Interrupt because Transmitter empty */
57          break;
58        case 4: /* Interrupt because Received data available */
59          break;
60        case 6: /* Interrupt because Status Register */
61          break;
62        case 12: /* Interrupt because of character timeout (16550 only) */
63          break;
64        default: /* No interrupt */
65          break;
66        }
67    }
68
69  if(old_handler)
70    (*old_handler)(vector,pc,effective_addr,status);
71}
72
73rtems_device_driver console_initialize(
74  rtems_device_major_number  major,
75  rtems_device_minor_number  minor,
76  void                      *arg
77)
78{
79  rtems_status_code status;
80  int tmp,tmp2;
81  uint32_t   sr;
82  extern uint32_t   Or1k_Interrupt_Vectors[16];
83
84  /* Make sure the UART (interrupt 2) is enabled and
85     reports a low prority interrupt */
86  asm volatile ("l.mfspr %0,r0,0x4800  \n\t"  /* Get the PIC mask */
87                "l.ori   %0,%0,0x4     \n\t"  /* Enable int 2 */
88                "l.mtspr r0,%0,0x4800  \n\t"  /* Write back mask */
89                "l.mfspr %0,r0,0x4801  \n\t"  /* Get priority mask */
90                "l.addi  %1,r0,-5      \n\t"
91                "l.and   %0,%0,%1      \n\t"  /* Set us to low */
92                "l.mtspr r0,%0,0x4801  \n\t"  /* Write back to PICPR */
93                : "=r" (tmp), "=r" (tmp2));
94
95  /* Install the interrupt handler */
96  asm volatile ("l.mfspr %0,r0,0x11 \n\t"
97                "l.addi  %1,r0,-5   \n\t"
98                "l.and   %1,%1,%0   \n\t"
99                "l.mtspr r0,%1,0x11 \n\t": "=&r" (sr) : "r" (tmp));
100
101  old_handler = (void(*)(unsigned int,unsigned int,unsigned int,unsigned int))
102    Or1k_Interrupt_Vectors[5];
103  Or1k_Interrupt_Vectors[5] = (uint32_t)console_interrupt;
104
105  asm volatile ("l.mtspr r0,%0,0x11\n\t":: "r" (sr));
106
107  /* Assume 1843.2/16 kHz clock */
108  uart->latch.LCR = 0x80;    /* Set the divisor latch bit */
109  uart->latch.DLM = 2;       /* 57,600 */
110  uart->latch.DLL = 0;
111  uart->write.LCR = 0x03;    /* 8-N-1 */
112  uart->write.MCR = 0x03;    /* Assert RTS & DTR */
113  /* uart->write.FCR = 0x00; */ /* Make sure we're in 16450 mode... Ignore for 16450 driver */
114  uart->write.IER = 0x05;    /* Don't worry about TEMT unless we need to. */
115
116  tmp = uart->read.LSR;     /* Make sure interrupts are cleared */
117  tmp = uart->read.RBR;     /* Clear the input buffer */
118  tmp = uart->read.MSR;     /* Clear the modem status register */
119
120  localEcho = 1;       /* Turn on local echo */
121
122  status = rtems_io_register_name(
123    "/dev/console",
124    major,
125    (rtems_device_minor_number) 0
126  );
127 
128  if (status != RTEMS_SUCCESSFUL)
129    rtems_fatal_error_occurred(status);
130 
131  return RTEMS_SUCCESSFUL;
132}
133
134
135/*  is_character_ready
136 *
137 *  This routine returns TRUE if a character is available.
138 *
139 *  Input parameters: NONE
140 *
141 *  Output parameters:  NONE
142 *
143 *  Return values:
144 */
145
146rtems_boolean is_character_ready(
147  char *ch
148)
149{
150  *ch = '\0';   /* return NULL for no particular reason */
151  return(TRUE);
152}
153
154/*  inbyte
155 *
156 *  This routine reads a character from the SOURCE.
157 *
158 *  Input parameters: NONE
159 *
160 *  Output parameters:  NONE
161 *
162 *  Return values:
163 *    character read from SOURCE
164 */
165
166char inbyte( void )
167{
168  unsigned int stat;
169
170  stat = uart->read.LSR;
171  while(!(stat & 0x01))  /* ! Data Ready */
172    {
173      rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
174      stat = uart->read.LSR;
175    }
176
177  return uart->read.RBR;   /* Return the character */
178}
179
180/*  outbyte
181 *
182 *  This routine transmits a character out the SOURCE.  Flow
183 *  control is not currently enabled.
184 *
185 *  Input parameters:
186 *    ch  - character to be transmitted
187 *
188 *  Output parameters:  NONE
189 */
190
191void outbyte(char ch)
192{
193  unsigned int stat;
194  /*
195   *  Carriage Return/New line translation.
196   */
197
198  stat = uart->read.LSR;
199  while(!(stat & 0x40))  /* ! TEMT */
200    {
201      rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
202      stat = uart->read.LSR;
203    }
204
205  uart->write.THR = ch;
206  if ( ch == '\n' )
207    outbyte( '\r' );
208}
209
210
211/*
212 *  Open entry point
213 */
214
215rtems_device_driver console_open(
216  rtems_device_major_number major,
217  rtems_device_minor_number minor,
218  void                    * arg
219)
220{
221  return RTEMS_SUCCESSFUL;
222}
223 
224/*
225 *  Close entry point
226 */
227
228rtems_device_driver console_close(
229  rtems_device_major_number major,
230  rtems_device_minor_number minor,
231  void                    * arg
232)
233{
234  return RTEMS_SUCCESSFUL;
235}
236
237/*
238 * read bytes from the serial port. We only have stdin.
239 */
240
241rtems_device_driver console_read(
242  rtems_device_major_number major,
243  rtems_device_minor_number minor,
244  void                    * arg
245)
246{
247  rtems_libio_rw_args_t *rw_args;
248  char *buffer;
249  int maximum;
250  int count = 0;
251 
252  rw_args = (rtems_libio_rw_args_t *) arg;
253
254  buffer = rw_args->buffer;
255  maximum = rw_args->count;
256
257 
258  for (count = 0; count < maximum; count++)
259    {
260      buffer[ count ] = inbyte();
261
262      if (buffer[ count ] == '\n' || buffer[ count ] == '\r')
263        {
264          buffer[ count++ ]  = '\n';
265          if(localEcho)
266            outbyte('\n' ); /* newline */
267          break;  /* Return for a newline */
268        }
269      else if (buffer[ count ] == '\b' && count > 0 )
270        {
271          if(localEcho)
272            {
273              outbyte('\b' ); /* move back one space */
274              outbyte(' ' ); /* erase the character */
275              outbyte('\b' ); /* move back one space */
276            }
277          count-=2;
278        }
279      else if(localEcho)
280        outbyte(buffer[ count ]); /* echo the character */
281    }
282
283  rw_args->bytes_moved = count;
284  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
285}
286
287/*
288 * write bytes to the serial port. Stdout and stderr are the same.
289 */
290
291rtems_device_driver console_write(
292  rtems_device_major_number major,
293  rtems_device_minor_number minor,
294  void                    * arg
295)
296{
297  int count;
298  int maximum;
299  rtems_libio_rw_args_t *rw_args;
300  char *buffer;
301
302  rw_args = (rtems_libio_rw_args_t *) arg;
303
304  buffer = rw_args->buffer;
305  maximum = rw_args->count;
306
307  for (count = 0; count < maximum; count++) {
308    if ( buffer[ count ] == '\n') {
309      outbyte('\r');
310    }
311    outbyte( buffer[ count ] );
312  }
313
314  rw_args->bytes_moved = maximum;
315  return 0;
316}
317
318/*
319 *  IO Control entry point
320 */
321
322rtems_device_driver console_control(
323  rtems_device_major_number major,
324  rtems_device_minor_number minor,
325  void                    * arg
326)
327{
328  int param,div;
329  ConsoleIOCTLRequest* request = (ConsoleIOCTLRequest*)arg;
330
331  if (!arg)
332    return RTEMS_INVALID_ADDRESS;
333
334  switch(request->command)
335    {
336    case TERM_LOCAL_ECHO:
337      param = (int)(request->data);
338      if(param < 0 || param > 1)
339        return RTEMS_INVALID_NUMBER;
340      localEcho = param;
341      break;
342    case TERM_BIT_RATE:
343      param = (int)(request->data);
344      switch(param)
345        {
346        case 50:
347        case 150:
348        case 300:
349        case 600:
350        case 1200:
351        case 1800:
352        case 2000:
353        case 2400:
354        case 3600:
355        case 4800:
356        case 7200:
357        case 9600:
358        case 19200:
359        case 38400:
360        case 57600:
361        case 115200:
362          div = 115200/param;
363          uart->latch.LCR |= 0x80;    /* Set the divisor latch bit */
364          uart->latch.DLM = div & 0xFF;
365          uart->latch.DLL = div >> 8;
366          uart->write.LCR &= 0x7F;    /* Clear the divisor latch bit */
367          break;
368        default:
369          return RTEMS_INVALID_NUMBER;
370        }
371      break;
372    default:
373      return RTEMS_NOT_CONFIGURED;
374    }
375
376  return RTEMS_SUCCESSFUL;
377}
Note: See TracBrowser for help on using the repository browser.