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

4.115
Last change on this file since d4ab6611 was d4ab6611, checked in by Joel Sherrill <joel.sherrill@…>, on 10/15/14 at 19:21:20

powerpc/score603e: Fix warnings

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