source: rtems/c/src/lib/libbsp/m68k/efi332/console/console.c @ f52111f

4.104.114.84.95
Last change on this file since f52111f was 08311cc3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/17/99 at 17:51:34

Updated copyright notice.

  • Property mode set to 100644
File size: 9.2 KB
Line 
1/*
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$
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
23char xmt_buf[BUFFER_LENGTH];
24char 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 */
29struct UART_buf {
30  char *offset;
31  char *in;
32  char *out;
33};
34static volatile struct UART_buf  xmt = { xmt_buf, (char *)0, (char *)1};
35static volatile struct UART_buf  rcv = { rcv_buf, (char *)0, (char *)1};
36static 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 */
43extern void _catchSCIint();
44asm("   .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
54extern void _catchCTSint();
55asm("   .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
65extern void _catchSPURIOUSint();
66asm("   .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
76int _spurious_int_counter=0;
77
78/* note: cts uses int1. If it "bounces", a spurious interrupt is generated */
79void 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 ******* */
87asm("   .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 */
97void xmit_interrupt(void);
98void rcvr_interrupt(void);
99void _fake_trap_1(void);
100
101void 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 */
118void 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 */
144void 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
172void 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 */
186char 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 */
204void 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
217void _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 
236void 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
250rtems_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
281rtems_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 
295rtems_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 
308rtems_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 
321rtems_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 
353rtems_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 
384rtems_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
Note: See TracBrowser for help on using the repository browser.