source: rtems/c/src/lib/libbsp/i386/shared/comm/tty_drv.c @ 8ad5399

4.104.114.84.95
Last change on this file since 8ad5399 was 8ad5399, checked in by Joel Sherrill <joel.sherrill@…>, on 10/18/00 at 16:10:50

2000-10-18 Charles-Antoine Gauthier <charles.gauthier@…>

  • comm/i386-stub-glue.c, comm/tty_drv.c, comm/uart.c, comm/uart.h: Add the ability to set parity, number of data bits and number of stop bits to the existing i386 serial drivers.
  • Property mode set to 100644
File size: 11.1 KB
Line 
1/***************************************************************************
2 *
3 * $Header$
4 *
5 * MODULE DESCRIPTION:
6 * This module implements the RTEMS drivers for the PC serial ports
7 * as /dev/ttyS1 for COM1 and /dev/ttyS2 as COM2. If one of the ports
8 * is used as the console, this driver would fail to initialize.
9 *
10 * This code was based on the console driver. It is based on the
11 * current termios framework. This is just a shell around the
12 * termios support.
13 *
14 * by: Rosimildo da Silva:
15 *     rdasilva@connecttel.com
16 *     http://www.connecttel.com
17 *
18 * MODIFICATION/HISTORY:
19 *
20 * $Log$
21 * Revision 1.1  2000/08/30 08:18:56  joel
22 * 2000-08-26  Rosimildo da Silva  <rdasilva@connecttel.com>
23 *
24 *      * shared/comm: Added "/dev/ttyS1" & "/dev/ttyS2" support for
25 *      the i386 BSPs.
26 *      * shared/comm/gdb_glue.c: New file.
27 *      * shared/comm/i386_io.c: New file.
28 *      * shared/comm/tty_drv.c: New file.
29 *      * shared/comm/tty_drv.h: New file.
30 *      * shared/comm/Makefile.am: Account for new files.
31 *      * shared/comm/uart.c: Adds support for sending characters to
32 *      another "line discipline."
33 *
34 ****************************************************************************/
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <assert.h>
39
40#include <bsp.h>
41#include <irq.h>
42#include <rtems/libio.h>
43#include <termios.h>
44#include <uart.h>
45#include <libcpu/cpuModel.h>
46
47int BSP_poll_read(int);
48
49/* Internal routines */
50static int tty1_conSetAttr( int minor, const struct termios *t);
51static int tty2_conSetAttr( int minor, const struct termios *t);
52static void isr_on(const rtems_irq_connect_data *);
53static void isr_off(const rtems_irq_connect_data *);
54static int  isr_is_on(const rtems_irq_connect_data *);
55
56
57extern BSP_polling_getchar_function_type BSP_poll_char;
58extern int BSPConsolePort;
59extern void rtems_set_waiting_id_comx( int port,  rtems_id id, rtems_event_set event );
60
61
62/*
63 * Interrupt structure for tty1
64 */
65static rtems_irq_connect_data tty1_isr_data =
66{
67  BSP_UART_COM1_IRQ,
68  BSP_uart_termios_isr_com1,
69  isr_on,
70  isr_off,
71  isr_is_on};
72
73/*
74 * Interrupt structure for tty2
75 */
76static rtems_irq_connect_data tty2_isr_data =
77{
78  BSP_UART_COM2_IRQ,
79  BSP_uart_termios_isr_com2,
80  isr_on,
81  isr_off,
82  isr_is_on};
83
84static void
85isr_on(const rtems_irq_connect_data *unused)
86{
87  return;
88}
89                                                   
90static void
91isr_off(const rtems_irq_connect_data *unused)
92{
93  return;
94}
95
96static int
97isr_is_on(const rtems_irq_connect_data *irq)
98{
99  return BSP_irq_enabled_at_i8259s(irq->name);
100}
101
102void tty_reserve_resources(rtems_configuration_table *conf)
103{
104  rtems_termios_reserve_resources(conf, 1);
105  return;
106}
107
108/*
109 *  TTYS1 - device driver INITIALIZE entry point.
110 */
111rtems_device_driver
112tty1_initialize(rtems_device_major_number major,
113                   rtems_device_minor_number minor,
114                   void                      *arg)
115{
116  rtems_status_code status;
117
118  /* Check if this port is not been used as console */
119  if( BSPConsolePort == BSP_UART_COM1 )
120  {
121    status = -1;
122    printk("TTYS1: port selected as console.\n");
123    rtems_fatal_error_occurred( status );
124  }
125
126  /*
127   * Set up TERMIOS
128   */
129  rtems_termios_initialize();
130 
131  /*
132   * Do device-specific initialization
133   */
134  /* 9600-8-N-1, without hardware flow control */
135  BSP_uart_init( BSP_UART_COM1, 9600, CHR_8_BITS, 0, 0, 0 );
136  status = BSP_install_rtems_irq_handler( &tty1_isr_data );
137  if( !status )
138  {
139    printk("Error installing ttyS1 interrupt handler!\n");
140    rtems_fatal_error_occurred(status);
141  }
142  /*
143   * Register the device
144   */
145  status = rtems_io_register_name ("/dev/ttyS1", major, 0);
146  if (status != RTEMS_SUCCESSFUL)
147  {
148      printk("Error registering ttyS1 device!\n");
149      rtems_fatal_error_occurred (status);
150  }
151  printk("Device: /dev/ttyS1 initialized.\n");
152  return RTEMS_SUCCESSFUL;
153} /* tty_initialize */
154
155
156static int tty1_last_close(int major, int minor, void *arg)
157{
158  BSP_remove_rtems_irq_handler( &tty1_isr_data );
159  return 0;
160}
161
162/*
163 * TTY1 - device driver OPEN entry point
164 */
165rtems_device_driver
166tty1_open(rtems_device_major_number major,
167                rtems_device_minor_number minor,
168                void                      *arg)
169{
170  rtems_status_code  status;
171  static rtems_termios_callbacks cb =
172  {
173    NULL,                     /* firstOpen */
174    tty1_last_close,       /* lastClose */
175    NULL,                 /* poll read  */
176    BSP_uart_termios_write_com1, /* write */
177    tty1_conSetAttr,         /* setAttributes */
178    NULL,                     /* stopRemoteTx */
179    NULL,                     /* startRemoteTx */
180    1                         /* outputUsesInterrupts */
181  };
182
183  status = rtems_termios_open( major, minor, arg, &cb );
184  if(status != RTEMS_SUCCESSFUL)
185  {
186     printk("Error openning tty1 device\n");
187     return status;
188  }
189
190  /*
191   * Pass data area info down to driver
192   */
193  BSP_uart_termios_set( BSP_UART_COM1,
194                       ((rtems_libio_open_close_args_t *)arg)->iop->data1 );
195  /* Enable interrupts  on channel */
196  BSP_uart_intr_ctrl( BSP_UART_COM1, BSP_UART_INTR_CTRL_TERMIOS);
197  return RTEMS_SUCCESSFUL;
198}
199
200/*
201 * TTY - device driver CLOSE entry point
202 */
203rtems_device_driver
204tty_close(rtems_device_major_number major,
205              rtems_device_minor_number minor,
206              void                      *arg)
207{
208
209  return (rtems_termios_close (arg));
210 
211} /* tty_close */
212
213 
214/*
215 * TTY device driver READ entry point.
216 * Read characters from the tty device.
217 */
218rtems_device_driver
219tty_read(rtems_device_major_number major,
220             rtems_device_minor_number minor,
221             void                      *arg)
222{
223  return rtems_termios_read (arg);
224} /* tty_read */
225 
226
227/*
228 * TTY device driver WRITE entry point.
229 * Write characters to the tty device.
230 */
231rtems_device_driver
232tty_write(rtems_device_major_number major,
233              rtems_device_minor_number minor,
234              void                    * arg)
235{
236    return rtems_termios_write (arg);
237 
238} /* tty_write */
239
240/*
241 * Handle ioctl request. This is a generic internal
242 * routine to handle both devices.
243 */
244static rtems_device_driver tty_control( int port, void  *arg )
245{
246        rtems_libio_ioctl_args_t *args = arg;
247        switch( args->command )
248        {
249           default:
250      return rtems_termios_ioctl (arg);
251                break;
252   }
253        args->ioctl_return = 0;
254   return RTEMS_SUCCESSFUL;
255}
256
257
258
259/*
260 * Handle ioctl request for ttyS1.
261 */
262rtems_device_driver
263tty1_control(rtems_device_major_number major,
264                rtems_device_minor_number minor,
265                void                      * arg
266)
267{
268  return tty_control( BSP_UART_COM1, arg );
269}
270
271
272static int
273conSetAttr(int port, int minor, const struct termios *t)
274{
275  unsigned long baud, databits, parity, stopbits;
276
277  switch (t->c_cflag & CBAUD)
278    {
279    case B50:   
280      baud = 50;
281      break;
282    case B75:   
283      baud = 75;       
284      break;
285    case B110: 
286      baud = 110;       
287      break;
288    case B134: 
289      baud = 134;       
290      break;
291    case B150: 
292      baud = 150;       
293      break;
294    case B200:
295      baud = 200;       
296      break;
297    case B300: 
298      baud = 300;
299      break;
300    case B600: 
301      baud = 600;       
302      break;
303    case B1200:
304      baud = 1200;
305      break;
306    case B1800:
307      baud = 1800;     
308      break;
309    case B2400:
310      baud = 2400;
311      break;
312    case B4800:
313      baud = 4800;
314      break;
315    case B9600:
316      baud = 9600;
317      break;
318    case B19200:
319      baud = 19200;
320      break;
321    case B38400:
322      baud = 38400;
323      break;
324    case B57600:       
325      baud = 57600;
326      break;
327    case B115200:
328      baud = 115200;
329      break;
330    default:
331      baud = 0;
332      rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
333      return 0;
334    }
335  if (t->c_cflag & PARENB) {
336    /* Parity is enabled */
337    if (t->c_cflag & PARODD) {
338      /* Parity is odd */
339      parity = PEN;
340    }
341    else {
342      /* Parity is even */
343      parity = PEN | EPS;
344    }
345  }
346  else {
347    /* No parity */
348    parity = 0;
349  }
350 
351  switch (t->c_cflag & CSIZE) {
352    case CS5: databits = CHR_5_BITS; break;
353    case CS6: databits = CHR_6_BITS; break;
354    case CS7: databits = CHR_7_BITS; break;
355    case CS8: databits = CHR_8_BITS; break;
356  }
357
358  if (t->c_cflag & CSTOPB) {
359    /* 2 stop bits */
360    stopbits = STB;
361  }
362  else {
363    /* 1 stop bit */
364    stopbits = 0;
365  }
366
367  printk("Setting attributes, port=%X, baud=%d, linemode = 0x%02x\n", port, baud, databits | parity | stopbits );
368  BSP_uart_set_attributes(port, baud, databits, parity, stopbits);
369  return 0;
370}
371
372/*
373 * Handle ioctl request for ttyS2.
374 */
375static int
376tty1_conSetAttr( int minor, const struct termios *t)
377{
378  return conSetAttr( BSP_UART_COM1, minor, t );
379}
380
381
382
383/*
384 * TTY2 device driver INITIALIZE entry point.
385 */
386rtems_device_driver
387tty2_initialize(rtems_device_major_number major,
388                   rtems_device_minor_number minor,
389                   void                      *arg)
390{
391  rtems_status_code status;
392
393  /* Check if this port is not been used as console */
394  if( BSPConsolePort == BSP_UART_COM2 )
395  {
396    status = -1;
397    printk("TTY2: port selected as console.\n");
398    rtems_fatal_error_occurred( status );
399  }
400
401  /*
402   * Set up TERMIOS
403   */
404  rtems_termios_initialize();
405 
406  /*
407   * Do device-specific initialization
408   */
409  /* 9600-8-N-1, without hardware flow control */
410  BSP_uart_init( BSP_UART_COM2, 9600, CHR_8_BITS, 0, 0, 0);
411  status = BSP_install_rtems_irq_handler( &tty2_isr_data );
412  if( !status )
413  {
414    printk("Error installing serial console interrupt handler!\n");
415    rtems_fatal_error_occurred(status);
416  }
417  /*
418   * Register the device
419   */
420  status = rtems_io_register_name ("/dev/ttyS2", major, 0);
421  if (status != RTEMS_SUCCESSFUL)
422  {
423      printk("Error registering tty2 device!\n");
424      rtems_fatal_error_occurred (status);
425  }
426  printk("Device: /dev/ttyS2 initialized.\n");
427  return RTEMS_SUCCESSFUL;
428} /* tty_initialize */
429
430
431static int tty2_last_close(int major, int minor, void *arg)
432{
433  BSP_remove_rtems_irq_handler( &tty2_isr_data );
434  return 0;
435}
436
437/*
438 * TTY2 device driver OPEN entry point
439 */
440rtems_device_driver
441tty2_open(rtems_device_major_number major,
442                rtems_device_minor_number minor,
443                void                      *arg)
444{
445  rtems_status_code              status;
446  static rtems_termios_callbacks cb =
447  {
448    NULL,                     /* firstOpen */
449    tty2_last_close,       /* lastClose */
450    NULL,                 /* poll read  */
451    BSP_uart_termios_write_com2, /* write */
452    tty2_conSetAttr,                  /* setAttributes */
453    NULL,                     /* stopRemoteTx */
454    NULL,                     /* startRemoteTx */
455    1                         /* outputUsesInterrupts */
456  };
457
458  status = rtems_termios_open (major, minor, arg, &cb);
459  if(status != RTEMS_SUCCESSFUL)
460  {
461     printk("Error openning tty1 device\n");
462     return status;
463  }
464
465  /*
466   * Pass data area info down to driver
467   */
468  BSP_uart_termios_set( BSP_UART_COM2,
469                         ((rtems_libio_open_close_args_t *)arg)->iop->data1 );
470   /* Enable interrupts  on channel */
471  BSP_uart_intr_ctrl( BSP_UART_COM2, BSP_UART_INTR_CTRL_TERMIOS);
472  return RTEMS_SUCCESSFUL;
473}
474
475/*
476 * Handle ioctl request for TTY2
477 */
478rtems_device_driver
479tty2_control(rtems_device_major_number major,
480                rtems_device_minor_number minor,
481                void                      * arg
482)
483{
484   return tty_control( BSP_UART_COM2, arg );
485}
486
487static int
488tty2_conSetAttr( int minor, const struct termios *t)
489{
490  return conSetAttr( BSP_UART_COM2, minor, t );
491}
Note: See TracBrowser for help on using the repository browser.