source: rtems/c/src/lib/libbsp/powerpc/score603e/console/console.c @ 9345c7d

4.104.115
Last change on this file since 9345c7d was 9345c7d, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 7, 2009 at 3:49:23 PM

2009-08-07 Joel Sherrill <joel.sherrill@…>

  • console/console.c, startup/genpvec.c, startup/setvec.c: Disable call to rtems_interrupt_catch until it is fixed. Need to disabled set_vector.
  • Property mode set to 100644
File size: 9.2 KB
Line 
1/*
2 *  This file contains the TTY driver for the serial ports on the SCORE603e.
3 *
4 *  This driver uses the termios pseudo driver.
5 *
6 *  Currently only polled mode is supported.
7 *
8 *  COPYRIGHT (c) 1989-2009.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.com/license/LICENSE.
14 *
15 *  $Id$
16 */
17
18#include <bsp.h>
19#include <rtems/libio.h>
20#include <stdlib.h>
21#include <assert.h>
22
23#include "consolebsp.h"
24#include <rtems/bspIo.h>
25
26/*
27 * The Port Used for the Console interface is based upon which
28 * debugger is being used.  The SDS debugger uses a binary
29 * interface on port 0 as part of the debugger.  Thus port 0 can
30 * not be used as the console port for the SDS debugger.
31 */
32
33#define USE_FOR_CONSOLE_DEF  0
34int USE_FOR_CONSOLE = USE_FOR_CONSOLE_DEF;
35
36/*
37 *
38 *  Console Device Driver Entry Points
39 */
40
41/* PAGE
42 *
43 *  console_inbyte_nonblocking
44 *
45 *  Console Termios polling input entry point.
46 */
47
48int console_inbyte_nonblocking(
49  int minor
50)
51{
52  int                       port = minor;
53
54  /*
55   * verify port Number
56   */
57  assert ( port < NUM_Z85C30_PORTS );
58
59  /*
60   * return a character from the 85c30 port.
61   */
62  return inbyte_nonblocking_85c30( &Ports_85C30[ port ] );
63}
64
65rtems_device_driver console_close(
66  rtems_device_major_number major,
67  rtems_device_minor_number minor,
68  void                    * arg
69)
70{
71  return rtems_termios_close (arg);
72}
73
74rtems_device_driver console_read(
75  rtems_device_major_number major,
76  rtems_device_minor_number minor,
77  void                    * arg
78)
79{
80  return rtems_termios_read (arg);
81}
82
83rtems_device_driver console_write(
84  rtems_device_major_number major,
85  rtems_device_minor_number minor,
86  void                    * arg
87)
88{
89  return rtems_termios_write (arg);
90}
91
92rtems_device_driver console_control(
93  rtems_device_major_number major,
94  rtems_device_minor_number minor,
95  void                    * arg
96)
97{
98  return rtems_termios_ioctl (arg);
99}
100
101/*
102 *  Interrupt driven console IO
103 */
104
105#if CONSOLE_USE_INTERRUPTS
106
107rtems_isr console_isr(
108  rtems_vector_number vector
109)
110{
111  int  i;
112
113  for (i=0; i < NUM_Z85C30_PORTS; i++){
114      ISR_85c30_Async( &Ports_85C30[i] );
115  }
116}
117
118void console_exit()
119{
120  int i;
121  volatile Ring_buffer_t *buffer;
122  uint32_t         ch;
123
124  for ( i=0 ; i < NUM_Z85C30_PORTS ; i++ ) {
125
126    buffer = &( Ports_85C30[i].Protocol->TX_Buffer);
127
128    while ( !Ring_buffer_Is_empty( buffer ) ) {
129      Ring_buffer_Remove_character( buffer, ch );
130      outbyte_polled_85c30( Ports_85C30[i].ctrl, ch );
131    }
132  }
133}
134
135void console_initialize_interrupts( void )
136{
137  volatile Ring_buffer_t     *buffer;
138  Console_Protocol  *protocol;
139  int               i;
140
141  for ( i=0 ; i < NUM_Z85C30_PORTS ; i++ ) {
142    protocol = Ports_85C30[i].Protocol;
143
144    /*
145     * Initialize the ring buffer and set to not transmitting.
146     */
147    buffer = &protocol->TX_Buffer;
148    Ring_buffer_Initialize( buffer );
149    protocol->Is_TX_active = false;
150  }
151
152  /*
153   * Connect each vector to the interupt service routine.
154   */
155  for (i=0; i < NUM_Z85C30_CHIPS; i++)
156    set_vector( console_isr, Chips_85C30[i].vector, 1 );
157  #warning "Install interrupts using proper method for PIC vectors."
158
159  atexit( console_exit );
160
161}
162void console_outbyte_interrupts(
163  const Port_85C30_info *Port,
164  char ch
165);
166
167#endif
168
169/* PAGE
170 *
171 *  console_initialize
172 *
173 *  Routine called to initialize the console device driver.
174 */
175rtems_device_driver console_initialize(
176  rtems_device_major_number  major,
177  rtems_device_minor_number  minor,
178  void                      *arg
179)
180{
181  rtems_status_code          status;
182  rtems_device_minor_number  console;
183  int                        port, chip, p0,p1;
184
185  /*
186   * initialize the termio interface.
187   */
188  rtems_termios_initialize();
189
190  /*
191   *  Register Device Names
192   */
193  console = USE_FOR_CONSOLE;
194  status = rtems_io_register_name( "/dev/console", major, console );
195  if (status != RTEMS_SUCCESSFUL)
196    rtems_fatal_error_occurred(status);
197
198  /*
199   *  Initialize Hardware
200   */
201
202/*
203 * INITIALIZE_COM_PORTS is defined in the linker script.  If it is
204 * true all serial chips on the board are to be reset at startup
205 * otherwise the reset is assumed to occur elsewhere (ie. in the
206 * debugger...)
207 */
208#if ( INITIALIZE_COM_PORTS )
209  /*
210   * Force to perform a hardware reset w/o
211   * Master interrupt enable via register 9
212   */
213
214  for (port=0; port<NUM_Z85C30_PORTS; port++){
215    p0 = port;
216    port++;
217    p1 = port;
218    Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
219  }
220#else
221  /* TEMP - To see if this makes a diff with the new ports.
222   *        Never reset chip 1 when using the chip as a monitor
223   */
224  for (port=2; port<NUM_Z85C30_PORTS; port++){
225    p0 = port;
226    port++;
227    p1 = port;
228    Reset_85c30_chip( Ports_85C30[p0].ctrl, Ports_85C30[p1].ctrl );
229  }
230#endif
231
232  /*
233   * Initialize each port.
234   * Note:  the ports are numbered such that 0,1 are on the first chip
235   *        2,3 are on the second ....
236   */
237
238  for (port=1; port<NUM_Z85C30_PORTS; port++) {
239   chip = port >> 1;
240    initialize_85c30_port( &Ports_85C30[port] );
241  }
242
243#if CONSOLE_USE_INTERRUPTS
244  console_initialize_interrupts();
245#endif
246
247  return RTEMS_SUCCESSFUL;
248}
249
250/* PAGE
251 *
252 *  console_write_support
253 *
254 *  Console Termios output entry point.
255 *
256 */
257int console_write_support(
258  int   minor,
259  const char *buf,
260  int   len)
261{
262  int nwrite = 0;
263  volatile uint8_t         *csr;
264  int                       port = minor;
265
266  /*
267   * verify port Number
268   */
269  assert ( port < NUM_Z85C30_PORTS );
270
271  /*
272   * Set the csr based upon the port number.
273   */
274  csr = Ports_85C30[ port ].ctrl;
275
276  /*
277   * poll each byte in the string out of the port.
278   */
279  while (nwrite < len) {
280#if (CONSOLE_USE_INTERRUPTS)
281    console_outbyte_interrupts( &Ports_85C30[ port ], *buf++ );
282#else
283    outbyte_polled_85c30( csr, *buf++ );
284#endif
285   nwrite++;
286  }
287
288  /*
289   * return the number of bytes written.
290   */
291  return nwrite;
292}
293
294/* PAGE
295 *
296 *  console_open
297 *
298 *  open a port as a termios console.
299 *
300 */
301rtems_device_driver console_open(
302  rtems_device_major_number major,
303  rtems_device_minor_number minor,
304  void                    * arg
305)
306{
307  rtems_status_code sc;
308  int               port = minor;
309#if (CONSOLE_USE_INTERRUPTS)
310  rtems_libio_open_close_args_t *args = arg;
311  static const rtems_termios_callbacks intrCallbacks = {
312    NULL,                       /* firstOpen */
313    NULL,                       /* lastClose */
314    NULL,                       /* pollRead */
315    console_write_support,      /* write */
316    NULL,                       /* setAttributes */
317    NULL,                       /* stopRemoteTx */
318    NULL,                       /* startRemoteTx */
319    1                           /* outputUsesInterrupts */
320  };
321#else
322  static const rtems_termios_callbacks pollCallbacks = {
323    NULL,                       /* firstOpen */
324    NULL,                       /* lastClose */
325    console_inbyte_nonblocking, /* pollRead */
326    console_write_support,      /* write */
327    NULL,                       /* setAttributes */
328    NULL,                       /* stopRemoteTx */
329    NULL,                       /* startRemoteTx */
330    0                           /* outputUsesInterrupts */
331  };
332#endif
333
334  /*
335   * Verify the minor number is valid.
336   */
337  if (minor < 0)
338    return RTEMS_INVALID_NUMBER;
339
340  if ( port > NUM_Z85C30_PORTS )
341     return RTEMS_INVALID_NUMBER;
342
343  /*
344   *  open the port as a termios console driver.
345   */
346
347#if (CONSOLE_USE_INTERRUPTS)
348   sc = rtems_termios_open( major, minor, arg, &intrCallbacks );
349
350   Ports_85C30[ minor ].Protocol->console_termios_data = args->iop->data1;
351#else
352   sc = rtems_termios_open( major, minor, arg, &pollCallbacks );
353#endif
354
355  return sc;
356}
357
358#if (CONSOLE_USE_INTERRUPTS)
359
360/*
361 *  console_outbyte_interrupts
362 *
363 *  This routine transmits a character out.
364 *
365 *  Input parameters:
366 *    port - port to transmit character to
367 *    ch  - character to be transmitted
368 *
369 *  Output parameters:  NONE
370 *
371 *  Return values:      NONE
372 */
373void console_outbyte_interrupts(
374  const Port_85C30_info *Port,
375  char ch
376)
377{
378  Console_Protocol   *protocol;
379  uint32_t            isrlevel;
380
381  protocol = Port->Protocol;
382
383  /*
384   *  If this is the first character then we need to prime the pump
385   */
386
387  if ( protocol->Is_TX_active == false ) {
388
389    rtems_interrupt_disable( isrlevel );
390    protocol->Is_TX_active = true;
391    outbyte_polled_85c30( Port->ctrl, ch );
392    rtems_interrupt_enable( isrlevel );
393
394    return;
395  }
396
397  while ( Ring_buffer_Is_full( &protocol->TX_Buffer ) );
398
399  Ring_buffer_Add_character( &protocol->TX_Buffer, ch );
400}
401
402#endif
403
404/* const char arg to be compatible with BSP_output_char decl. */
405void
406debug_putc_onlcr(const char c)
407{
408  int                      console;
409  volatile uint8_t         *csr;
410  uint32_t                 isrlevel;
411
412  console = USE_FOR_CONSOLE;
413  csr = Ports_85C30[ console ].ctrl;
414
415  if ('\n'==c){
416    rtems_interrupt_disable( isrlevel );
417    outbyte_polled_85c30( csr, '\r' );
418    asm volatile("isync");
419    rtems_interrupt_enable( isrlevel );
420  }
421
422  rtems_interrupt_disable( isrlevel );
423  outbyte_polled_85c30( csr, c );
424  asm volatile("isync");
425  rtems_interrupt_enable( isrlevel );
426}
427
428BSP_output_char_function_type   BSP_output_char = debug_putc_onlcr;
429/* const char arg to be compatible with BSP_output_char decl. */
430
Note: See TracBrowser for help on using the repository browser.