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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [or1k/] [bender/] [console/] [console.c] - Blame information for rev 602

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

Line No. Rev Author Line
1 30 unneback
/*
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.OARcorp.com/rtems/license.html.
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
 
22
static int localEcho;
23
static 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
 
36
void (*old_handler)(unsigned int,unsigned int,unsigned int,unsigned int);
37
 
38
void 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
 
73
rtems_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
  unsigned32 sr;
82
  extern unsigned32 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] = (unsigned32)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
 
146
rtems_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
 
166
char 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
 
191
void 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
 
215
rtems_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
 
228
rtems_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
 
241
rtems_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
 
291
rtems_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
 
322
rtems_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
}

powered by: WebSVN 2.1.0

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