source: rtems/c/src/lib/libbsp/m68k/mrm332/console/console.c @ 66387986

4.104.114.84.95
Last change on this file since 66387986 was 332484b5, checked in by Joel Sherrill <joel.sherrill@…>, on 05/25/01 at 16:28:46

2000-05-25 Matt Cross <profesor@…>

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