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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [m68k/] [efi332/] [console/] [console.c] - Blame information for rev 773

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

Line No. Rev Author Line
1 30 unneback
/*
2
 *  This file contains the efi332 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
 *  $Id: console.c,v 1.2 2001-09-27 12:00:01 chris Exp $
12
 */
13
 
14
#include <stdlib.h>
15
#include <bsp.h>
16
#include <rtems/libio.h>
17
 
18
/* BUFFER_LENGTH must be 2^n for n=1, 2, 3, .... */
19
#define BUFFER_LENGTH 256
20
#define RTS_STOP_SIZE BUFFER_LENGTH-64
21
#define RTS_START_SIZE 16
22
 
23
char xmt_buf[BUFFER_LENGTH];
24
char rcv_buf[BUFFER_LENGTH];
25
/* in: last entry into the buffer; always on a valid character */
26
/* out: points to the next character to be pull from the buffer */
27
/*    in+1=out => buffer empty */
28
/*    in+2=out => buffer full */
29
struct UART_buf {
30
  char *offset;
31
  char *in;
32
  char *out;
33
};
34
static volatile struct UART_buf  xmt = { xmt_buf, (char *)0, (char *)1};
35
static volatile struct UART_buf  rcv = { rcv_buf, (char *)0, (char *)1};
36
static volatile char _debug_flag = 0;
37
 
38
#define SET_RTS(a) {*PORTF0 = (*PORTF0 & ~0x4) | ( (a)? 0 : 0x4); }
39
#define GET_CTS (!(*PORTF0 & 0x2))
40
 
41
/* _catchSCIint, _catchCTSint, and _catchSPURIOUSint are the
42
   interrupt front-ends */
43
extern void _catchSCIint();
44
asm("   .text
45
        .align 2
46
        .globl _catchSCIint
47
_catchSCIint:
48
        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */
49
        jbsr    uart_interrupt
50
        moveml  %sp@+,%d0-%d7/%a0-%a6
51
        rte
52
    ");
53
 
54
extern void _catchCTSint();
55
asm("   .text
56
        .align 2
57
        .globl _catchCTSint
58
_catchCTSint:
59
        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */
60
        jbsr    cts_interrupt
61
        moveml  %sp@+,%d0-%d7/%a0-%a6
62
        rte
63
    ");
64
 
65
extern void _catchSPURIOUSint();
66
asm("   .text
67
        .align 2
68
        .globl _catchSPURIOUSint
69
_catchSPURIOUSint:
70
        moveml %d0-%d7/%a0-%a6,%sp@-       /* save registers */
71
        jbsr    spurious_interrupt
72
        moveml  %sp@+,%d0-%d7/%a0-%a6
73
        rte
74
    ");
75
 
76
int _spurious_int_counter=0;
77
 
78
/* note: cts uses int1. If it "bounces", a spurious interrupt is generated */
79
void spurious_interrupt(void) {
80
  _spurious_int_counter++;      /* there should never be alot of these */
81
}
82
 
83
/* _fake_trap_1 will continue the UART interrupt (%sr *still*
84
   UART_ISR_LEVEL) as a trap #1 to enter the debugger */
85
 
86
/* *****fix me; this is for 68000 w/jsr ram exception table ******* */
87
asm("   .text
88
        .align 2
89
_fake_trap_1:
90
        unlk %a6                /* clear interrupt frame */
91
        lea %sp@(4),%sp         /* remove jbsr instruction */
92
        moveml %sp@+,%d0-%d7/%a0-%a6 /* pop registers */
93
        jmp (33*6-12)   /* jump exception 1 */
94
        ");
95
 
96
/* dispatch UART interrupt */
97
void xmit_interrupt(void);
98
void rcvr_interrupt(void);
99
void _fake_trap_1(void);
100
 
101
void uart_interrupt(void) {
102
  /* receiver status bits are cleared by a SCSR read followed
103
     by a SCDR read. transmitter status bits are cleared by
104
     a SCSR read followed by a SCDR write. */
105
  if ((*SCSR) & (TDRE | TC))
106
    xmit_interrupt();
107
 
108
  if ((*SCSR) & (RDRF))
109
    rcvr_interrupt();
110
 
111
  if (_debug_flag) {
112
    _debug_flag = 0;             /* reset the flag */
113
    _fake_trap_1();             /* fake a trap #1 */
114
  }
115
}
116
 
117
/* transfer received character to the buffer */
118
void rcvr_interrupt(void) {
119
  register char *a, c;
120
  register int length;
121
 
122
  while((*SCSR) & (RDRF)) {
123
    if ((c=*SCDR) == 0x1a)      /* use ctl-z to reboot */
124
      reboot();
125
/*     else if (c == 0x03) { */ /* use ctl-c to enter debugger */
126
/*       _debug_flag = 1; */
127
/*       continue; */
128
/*     } */
129
 
130
    *(char *)((int)rcv.offset +(int)
131
              (a=(char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1)))) = c;
132
    if ((char *)(((int)rcv.in+2) & ((int)BUFFER_LENGTH-1)) != rcv.out)
133
      rcv.in=a;
134
  };
135
 
136
  length = (BUFFER_LENGTH -1) & (
137
    ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out
138
    + (int)rcv.in + 1);
139
  if (length >= RTS_STOP_SIZE)
140
    SET_RTS(0);
141
}
142
 
143
/* tranfer buffered characters to the UART */
144
void xmit_interrupt(void) {
145
  register short int oldsr;
146
 
147
  _CPU_ISR_Disable( oldsr ); /* for when outbyte or flush calls */
148
  while ((*SCSR) & (TDRE)) {
149
    if ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)
150
      /* xmit buffer not empty */
151
      if (GET_CTS) {
152
        /* send next char */
153
        *SCDR=*(char *)((int)xmt.offset+(int)xmt.out);
154
        xmt.out= (char *)(((int)xmt.out+1) & ((int)BUFFER_LENGTH-1));
155
        *SCCR1 = (*SCCR1 & ~(TIE | TCIE)) | (TIE);
156
      }
157
      else {
158
        /* configue CTS interrupt and shutdown xmit interrupts */
159
        *SCCR1 &= ~(TIE | TCIE);
160
        *PFPAR |= 0x2;
161
        break;
162
      }
163
    else {
164
      /* xmit buffer empty; shutdown interrupts */
165
      *SCCR1 &= ~(TIE | TCIE);
166
      break;
167
    }
168
  }
169
  _CPU_ISR_Enable( oldsr );
170
}
171
 
172
void cts_interrupt(void) {
173
  register short int oldsr;
174
 
175
  _CPU_ISR_Disable( oldsr ); /* for when outbyte calls */
176
 
177
  *PFPAR &= ~0x2;
178
  *SCCR1 = (*SCCR1 & ~(TIE | TCIE)) | (TIE);
179
 
180
  _CPU_ISR_Enable( oldsr );
181
}
182
 
183
 
184
 
185
/* transfer character from the buffer */
186
char inbyte(void) {
187
  register char a;
188
  register int length;
189
 
190
  while ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out);
191
  a=*(char *)((int)rcv.offset+(int)rcv.out);
192
  rcv.out= (char *)(((int)rcv.out+1) & ((int)BUFFER_LENGTH-1));
193
  length = (BUFFER_LENGTH -1) & (
194
    ( ((int)rcv.out <= (int)rcv.in) ? 0 : BUFFER_LENGTH) - (int)rcv.out
195
    + (int)rcv.in + 1);
196
  if (length < RTS_START_SIZE)
197
    SET_RTS(1);
198
  return (a);
199
}
200
 
201
/* once room is avaliable in the buffer, transfer
202
   the character into the buffer and enable
203
   the xmtr interrupt */
204
void outbyte(char c) {
205
  register char *a;
206
 
207
  while ((char *)(((int)xmt.in+2) & ((int)BUFFER_LENGTH-1)) == xmt.out);
208
  *(char *)((int)xmt.offset+(int)
209
            (a=(char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1))))=c;
210
  xmt.in=a;
211
 
212
  if (!(*SCCR1 & (TIE | TCIE)) && (!(*PFPAR & 0x2)) )
213
                                /* if neither interrupts are running, */
214
    xmit_interrupt();           /*    we need to restart the xmiter */
215
}
216
 
217
void _UART_flush(void) {
218
  /* loop till xmt buffer empty. Works with interrupts disabled */
219
  while ((char *)(((int)xmt.in+1) & ((int)BUFFER_LENGTH-1)) != xmt.out)
220
    xmit_interrupt();
221
  /* loop till UART buffer empty */
222
  while ( (*SCSR & TC) == 0 );
223
}
224
 
225
/*  console_initialize
226
 *
227
 *  This routine initializes the console IO driver.
228
 *
229
 *  Input parameters: NONE
230
 *
231
 *  Output parameters:  NONE
232
 *
233
 *  Return values:
234
 */
235
 
236
void console_init()
237
{
238
  *QSMCR = ( SAM(QSM_IARB,0,IARB) );
239
  *QILR = ( SAM(ISRL_QSPI,4,ILQSPI) | SAM(ISRL_SCI,0,ILSCI) );
240
  *QIVR = ( SAM(EFI_QIVR,0,INTV) );
241
 
242
  *SCCR0 = ( (int)( SYS_CLOCK/SCI_BAUD/32.0+0.5 ) & 0x1fff );
243
  *SCCR1 = ( RIE | TE | RE );
244
 
245
  set_vector(_catchSPURIOUSint, EFI_SPINT, 0);
246
  set_vector(_catchSCIint, EFI_QIVR, 0);
247
  set_vector(_catchCTSint, EFI_INT1, 0);
248
}
249
 
250
rtems_device_driver console_initialize(
251
  rtems_device_major_number  major,
252
  rtems_device_minor_number  minor,
253
  void                      *arg
254
)
255
{
256
  rtems_status_code status;
257
 
258
  status = rtems_io_register_name(
259
    "/dev/console",
260
    major,
261
    (rtems_device_minor_number) 0
262
  );
263
 
264
  if (status != RTEMS_SUCCESSFUL)
265
    rtems_fatal_error_occurred(status);
266
 
267
  return RTEMS_SUCCESSFUL;
268
}
269
 
270
/*  is_character_ready
271
 *
272
 *  This routine returns TRUE if a character is available.
273
 *
274
 *  Input parameters: NONE
275
 *
276
 *  Output parameters:  NONE
277
 *
278
 *  Return values:
279
 */
280
 
281
rtems_boolean is_character_ready(
282
  char *ch
283
)
284
{
285
  if ((char *)(((int)rcv.in+1) & ((int)BUFFER_LENGTH-1))== rcv.out)
286
    return(FALSE);
287
  else
288
    return(TRUE);
289
}
290
 
291
/*
292
 *  Open entry point
293
 */
294
 
295
rtems_device_driver console_open(
296
  rtems_device_major_number major,
297
  rtems_device_minor_number minor,
298
  void                    * arg
299
)
300
{
301
  return RTEMS_SUCCESSFUL;
302
}
303
 
304
/*
305
 *  Close entry point
306
 */
307
 
308
rtems_device_driver console_close(
309
  rtems_device_major_number major,
310
  rtems_device_minor_number minor,
311
  void                    * arg
312
)
313
{
314
  return RTEMS_SUCCESSFUL;
315
}
316
 
317
/*
318
 * read bytes from the serial port. We only have stdin.
319
 */
320
 
321
rtems_device_driver console_read(
322
  rtems_device_major_number major,
323
  rtems_device_minor_number minor,
324
  void                    * arg
325
)
326
{
327
  rtems_libio_rw_args_t *rw_args;
328
  char *buffer;
329
  int maximum;
330
  int count;
331
 
332
  rw_args = (rtems_libio_rw_args_t *) arg;
333
 
334
  buffer = rw_args->buffer;
335
  maximum = rw_args->count;
336
 
337
  for (count = 0; count < maximum; count++) {
338
    buffer[ count ] = inbyte();
339
    if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
340
      buffer[ count++ ]  = '\n';
341
      break;
342
    }
343
  }
344
 
345
  rw_args->bytes_moved = count;
346
  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
347
}
348
 
349
/*
350
 * write bytes to the serial port. Stdout and stderr are the same.
351
 */
352
 
353
rtems_device_driver console_write(
354
  rtems_device_major_number major,
355
  rtems_device_minor_number minor,
356
  void                    * arg
357
)
358
{
359
  int count;
360
  int maximum;
361
  rtems_libio_rw_args_t *rw_args;
362
  char *buffer;
363
 
364
  rw_args = (rtems_libio_rw_args_t *) arg;
365
 
366
  buffer = rw_args->buffer;
367
  maximum = rw_args->count;
368
 
369
  for (count = 0; count < maximum; count++) {
370
    if ( buffer[ count ] == '\n') {
371
      outbyte('\r');
372
    }
373
    outbyte( buffer[ count ] );
374
  }
375
 
376
  rw_args->bytes_moved = maximum;
377
  return 0;
378
}
379
 
380
/*
381
 *  IO Control entry point
382
 */
383
 
384
rtems_device_driver console_control(
385
  rtems_device_major_number major,
386
  rtems_device_minor_number minor,
387
  void                    * arg
388
)
389
{
390
  return RTEMS_SUCCESSFUL;
391
}
392
 

powered by: WebSVN 2.1.0

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