source: rtems/c/src/lib/libbsp/m68k/uC5282/console/console.c @ 1c6926c1

Last change on this file since 1c6926c1 was 1c6926c1, checked in by Kevin Kirspel <kevin-kirspel@…>, on Mar 21, 2017 at 7:39:48 PM

termios: Synchronize with latest FreeBSD headers

Adding modified FreeBSD headers to synchronize RTEMS termios with
FreeBSD. Modify termios to support dedicated input and output baud for
termios structure. Updated BSPs to use dedicated input and output baud
in termios structure. Updated tools to use dedicated input and output
baud in termios structure. Updated termios testsuites to use dedicated
input and output baud in termios structure.

Close #2897.

  • Property mode set to 100644
File size: 21.8 KB
Line 
1/*
2 *  Multi UART console serial I/O.
3 *
4 * TO DO: Add DMA input/output
5 *
6 *  Author: W. Eric Norum <norume@aps.anl.gov>
7 *
8 *  COPYRIGHT (c) 2005.
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.org/license/LICENSE.
14 *
15 */
16
17#include <stdio.h>
18#include <fcntl.h>
19#include <termios.h>
20#include <malloc.h>
21
22#include <rtems/console.h>
23#include <rtems/libio.h>
24#include <rtems/termiostypes.h>
25#include <bsp.h>
26
27#include <rtems/bspIo.h>
28
29#define UART_INTC0_IRQ_VECTOR(x) (64+13+(x))
30
31#define MCF5282_UART_USR_ERROR ( MCF5282_UART_USR_RB | \
32                                 MCF5282_UART_USR_FE | \
33                                 MCF5282_UART_USR_PE | \
34                                 MCF5282_UART_USR_OE )
35
36static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len);
37static ssize_t IntUartInterruptWrite (int minor, const char *buf, size_t len);
38
39static void
40_BSP_null_char( char c )
41{
42        int level;
43
44    if (c == '\n')
45        _BSP_null_char('\r');
46        rtems_interrupt_disable(level);
47    while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 )
48        continue;
49    MCF5282_UART_UTB(CONSOLE_PORT) = c;
50    while ( (MCF5282_UART_USR(CONSOLE_PORT) & MCF5282_UART_USR_TXRDY) == 0 )
51        continue;
52        rtems_interrupt_enable(level);
53}
54
55BSP_polling_getchar_function_type       BSP_poll_char = NULL;
56BSP_output_char_function_type           BSP_output_char = _BSP_null_char;
57
58/*
59 * The MCF5282 has three UARTs.  Enable all them here.  I/O pin selection
60 * is assumed to have been done elsewher.
61 */
62#define MAX_UART_INFO     3
63#define RX_BUFFER_SIZE    512
64
65struct IntUartInfoStruct
66{
67        int                    iomode;
68        volatile int           uimr;
69        int                    baud;
70        int                    databits;
71        int                    parity;
72        int                    stopbits;
73        int                    hwflow;
74        int                    rx_in;
75        int                    rx_out;
76        char                   rx_buffer[RX_BUFFER_SIZE];
77        void                  *ttyp;
78};
79
80struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO];
81
82/***************************************************************************
83   Function : IntUartSet
84
85   Description : This updates the hardware UART settings.
86 ***************************************************************************/
87static void
88IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow)
89{
90        int                         divisor;
91        uint32_t                                        clock_speed;
92        uint8_t                   umr1 = 0;
93        uint8_t                   umr2 = 0;
94        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
95        int                         level;
96
97        rtems_interrupt_disable(level);
98
99
100        /* disable interrupts, clear RTS line, and disable the UARTS */
101        MCF5282_UART_UIMR(minor) = 0;
102        MCF5282_UART_UOP0(minor) = 1;
103        MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED);
104
105        /* save the current values */
106        info->uimr     = 0;
107        info->baud     = baud;
108        info->databits = databits;
109        info->parity   = parity;
110        info->stopbits = stopbits;
111        info->hwflow   = hwflow;
112
113    clock_speed = bsp_get_CPU_clock_speed();
114    /* determine the baud divisor value */
115    divisor = (clock_speed / ( 32 * baud ));
116    if ( divisor < 2 )
117        divisor = 2;
118
119        /* check to see if doing hardware flow control */
120        if ( hwflow )
121        {
122                /* set hardware flow options */
123                umr1 |= MCF5282_UART_UMR1_RXRTS;
124                umr2 |= MCF5282_UART_UMR2_TXCTS;
125        }
126
127        /* determine the new umr values */
128        umr1 |= (parity | databits);
129        umr2 |= (stopbits);
130
131        /* reset the uart */
132        MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_ERROR;
133        MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_RX;
134        MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_TX;
135
136        /* reset the uart mode register and update values */
137        MCF5282_UART_UCR(minor) = MCF5282_UART_UCR_RESET_MR;
138        MCF5282_UART_UMR(minor) = umr1;
139        MCF5282_UART_UMR(minor) = umr2;
140
141        /* set the baud rate values */
142        MCF5282_UART_UCSR(minor) = (MCF5282_UART_UCSR_RCS_SYS_CLK | MCF5282_UART_UCSR_TCS_SYS_CLK);
143        MCF5282_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
144        MCF5282_UART_UBG2(minor) = (divisor & 0x00ff);
145
146        /* enable the uart */
147    MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED);
148
149        /* check to see if interrupts need to be enabled */
150        if ( info->iomode != TERMIOS_POLLED )
151        {
152                /* enable rx interrupts */
153                info->uimr |= MCF5282_UART_UIMR_FFULL;
154                MCF5282_UART_UIMR(minor) = info->uimr;
155        }
156
157        /* check to see if doing hardware flow control */
158        if ( hwflow )
159        {
160                /* assert the RTS line */
161                MCF5282_UART_UOP1(minor) = 1;
162        }
163
164        rtems_interrupt_enable(level);
165
166}
167
168
169/***************************************************************************
170   Function : IntUartSetAttributes
171
172   Description : This provides the hardware-dependent portion of tcsetattr().
173   value and sets it. At the moment this just sets the baud rate.
174
175   Note: The highest baudrate is 115200 as this stays within
176   an error of +/- 5% at 25MHz processor clock
177 ***************************************************************************/
178static int
179IntUartSetAttributes(int minor, const struct termios *t)
180{
181        /* set default index values */
182        int                         baud     = (int)9600;
183        int                         databits = (int)MCF5282_UART_UMR1_BC_8;
184        int                         parity   = (int)MCF5282_UART_UMR1_PM_NONE;
185        int                         stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_1;
186        int                         hwflow   = (int)0;
187        struct IntUartInfoStruct   *info     = &IntUartInfo[minor];
188
189        /* check to see if input is valid */
190        if ( t != (const struct termios *)0 )
191        {
192                /* determine baud rate index */
193    baud = rtems_termios_baud_to_number(t->c_ospeed);
194
195                /* determine data bits */
196                switch ( t->c_cflag & CSIZE )
197                {
198                        case CS5:
199                                databits = (int)MCF5282_UART_UMR1_BC_5;
200                                break;
201                        case CS6:
202                                databits = (int)MCF5282_UART_UMR1_BC_6;
203                                break;
204                        case CS7:
205                                databits = (int)MCF5282_UART_UMR1_BC_7;
206                                break;
207                        case CS8:
208                                databits = (int)MCF5282_UART_UMR1_BC_8;
209                                break;
210                }
211
212                /* determine if parity is enabled */
213                if ( t->c_cflag & PARENB )
214                {
215                        if ( t->c_cflag & PARODD )
216                        {
217                                /* odd parity */
218                                parity = (int)MCF5282_UART_UMR1_PM_ODD;
219                        }
220                        else
221                        {
222                                /* even parity */
223                                parity = (int)MCF5282_UART_UMR1_PM_EVEN;
224                        }
225                }
226
227                /* determine stop bits */
228                if ( t->c_cflag & CSTOPB )
229                {
230                        /* two stop bits */
231                        stopbits = (int)MCF5282_UART_UMR2_STOP_BITS_2;
232                }
233
234                /* check to see if hardware flow control */
235                if ( t->c_cflag & CRTSCTS )
236                {
237                        hwflow = 1;
238                }
239        }
240
241        /* check to see if values have changed */
242        if ( ( baud     != info->baud     ) ||
243                 ( databits != info->databits ) ||
244                 ( parity   != info->parity   ) ||
245                 ( stopbits != info->stopbits ) ||
246                 ( hwflow   != info->hwflow   ) )
247        {
248
249                /* call function to set values */
250                IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
251        }
252
253        return( RTEMS_SUCCESSFUL );
254
255}
256
257/***************************************************************************
258   Function : IntUartInterruptHandler
259
260   Description : This is the interrupt handler for the internal uart. It
261   determines which channel caused the interrupt before queueing any received
262   chars and dequeueing chars waiting for transmission.
263 ***************************************************************************/
264static rtems_isr
265IntUartInterruptHandler(rtems_vector_number v)
266{
267        unsigned int                chan = v - UART_INTC0_IRQ_VECTOR(0);
268        struct IntUartInfoStruct   *info = &IntUartInfo[chan];
269
270        /* check to see if received data */
271        if ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_RXRDY )
272        {
273                /* read data and put into the receive buffer */
274                while ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_RXRDY )
275                {
276
277                        if ( MCF5282_UART_USR(chan) & MCF5282_UART_USR_ERROR )
278                        {
279                                /* clear the error */
280                                MCF5282_UART_UCR(chan) = MCF5282_UART_UCR_RESET_ERROR;
281                        }
282                        /* put data in rx buffer and check for errors */
283                        info->rx_buffer[info->rx_in] = MCF5282_UART_URB(chan);
284
285                        /* update buffer values */
286                        info->rx_in++;
287
288                        if ( info->rx_in >= RX_BUFFER_SIZE )
289                        {
290                                info->rx_in = 0;
291                        }
292                }
293                /* Make sure the port has been opened */
294                if ( info->ttyp )
295                {
296
297                        /* check to see if task driven */
298                        if ( info->iomode == TERMIOS_TASK_DRIVEN )
299                        {
300                                /* notify rx task that rx buffer has data */
301                                rtems_termios_rxirq_occured(info->ttyp);
302                        }
303                        else
304                        {
305                                /* Push up the received data */
306                                rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in);
307                                info->rx_in    = 0;
308                        }
309                }
310        }
311
312        /* check to see if data needs to be transmitted */
313        if ( ( info->uimr & MCF5282_UART_UIMR_TXRDY ) &&
314                 ( MCF5282_UART_UISR(chan) & MCF5282_UART_UISR_TXRDY ) )
315        {
316
317                /* disable tx interrupts */
318                info->uimr &= ~MCF5282_UART_UIMR_TXRDY;
319                MCF5282_UART_UIMR(chan) = info->uimr;
320
321                /* tell upper level that character has been sent */
322                if ( info->ttyp )
323                        rtems_termios_dequeue_characters(info->ttyp, 1);
324        }
325}
326
327
328
329/***************************************************************************
330   Function : IntUartInitialize
331
332   Description : This initialises the internal uart hardware for all
333   internal uarts. If the internal uart is to be interrupt driven then the
334   interrupt vectors are hooked.
335 ***************************************************************************/
336static void
337IntUartInitialize(void)
338{
339        unsigned int        chan;
340        struct IntUartInfoStruct   *info;
341        rtems_isr_entry old_handler;
342    int level;
343
344        for ( chan = 0; chan < MAX_UART_INFO; chan++ )
345        {
346                info = &IntUartInfo[chan];
347
348                info->ttyp     = NULL;
349                info->rx_in    = 0;
350                info->rx_out   = 0;
351                info->baud     = -1;
352                info->databits = -1;
353                info->parity   = -1;
354                info->stopbits = -1;
355                info->hwflow   = -1;
356
357                MCF5282_UART_UACR(chan) = 0;
358                MCF5282_UART_UIMR(chan) = 0;
359                if ( info->iomode != TERMIOS_POLLED )
360                {
361                        rtems_interrupt_catch (IntUartInterruptHandler,
362                                                                   UART_INTC0_IRQ_VECTOR(chan),
363                                                                   &old_handler);
364                }
365
366                /* set uart default values */
367                IntUartSetAttributes(chan, NULL);
368
369        /* unmask interrupt */
370                rtems_interrupt_disable(level);
371        switch(chan) {
372        case 0:
373            bsp_allocate_interrupt(UART0_IRQ_LEVEL, UART0_IRQ_PRIORITY);
374            MCF5282_INTC0_ICR13 = MCF5282_INTC_ICR_IL(UART0_IRQ_LEVEL) |
375                                  MCF5282_INTC_ICR_IP(UART0_IRQ_PRIORITY);
376            MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT13 |
377                                    MCF5282_INTC_IMRL_MASKALL);
378            break;
379
380        case 1:
381            bsp_allocate_interrupt(UART1_IRQ_LEVEL, UART1_IRQ_PRIORITY);
382            MCF5282_INTC0_ICR14 = MCF5282_INTC_ICR_IL(UART1_IRQ_LEVEL) |
383                                  MCF5282_INTC_ICR_IP(UART1_IRQ_PRIORITY);
384            MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT14 |
385                                    MCF5282_INTC_IMRL_MASKALL);
386            break;
387
388        case 2:
389            bsp_allocate_interrupt(UART2_IRQ_LEVEL, UART2_IRQ_PRIORITY);
390            MCF5282_INTC0_ICR15 = MCF5282_INTC_ICR_IL(UART2_IRQ_LEVEL) |
391                                  MCF5282_INTC_ICR_IP(UART2_IRQ_PRIORITY);
392            MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT15 |
393                                    MCF5282_INTC_IMRL_MASKALL);
394            break;
395        }
396                rtems_interrupt_enable(level);
397
398        } /* of chan loop */
399
400
401} /* IntUartInitialise */
402
403
404/***************************************************************************
405   Function : IntUartInterruptWrite
406
407   Description : This writes a single character to the appropriate uart
408   channel. This is either called during an interrupt or in the user's task
409   to initiate a transmit sequence. Calling this routine enables Tx
410   interrupts.
411 ***************************************************************************/
412static ssize_t
413IntUartInterruptWrite (int minor, const char *buf, size_t len)
414{
415        if (len > 0) {
416                /* write out character */
417                MCF5282_UART_UTB(minor) = *buf;
418
419                /* enable tx interrupt */
420                IntUartInfo[minor].uimr |= MCF5282_UART_UIMR_TXRDY;
421                MCF5282_UART_UIMR(minor) = IntUartInfo[minor].uimr;
422        }
423
424        return 0;
425}
426
427/***************************************************************************
428   Function : IntUartInterruptOpen
429
430   Description : This enables interrupts when the tty is opened.
431 ***************************************************************************/
432static int
433IntUartInterruptOpen(int major, int minor, void *arg)
434{
435        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
436        int level;
437
438        /*
439         * Enable serial I/O pin assignments
440         */
441        rtems_interrupt_disable(level);
442        switch(minor) {
443        case 0:
444                MCF5282_GPIO_PUAPAR |= MCF5282_GPIO_PUAPAR_PUAPA1|MCF5282_GPIO_PUAPAR_PUAPA0;
445                break;
446        case 1:
447                MCF5282_GPIO_PUAPAR |= MCF5282_GPIO_PUAPAR_PUAPA3|MCF5282_GPIO_PUAPAR_PUAPA2;
448                break;
449        case 2:
450                MCF5282_GPIO_PASPAR =
451                  (MCF5282_GPIO_PASPAR
452                   & ~(MCF5282_GPIO_PASPAR_PASPA3(3)|MCF5282_GPIO_PASPAR_PASPA2(3)))
453                  |  (MCF5282_GPIO_PASPAR_PASPA3(2)|MCF5282_GPIO_PASPAR_PASPA2(2));
454                break;
455        }
456        rtems_interrupt_enable(level);
457        /* enable the uart */
458        MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_ENABLED | MCF5282_UART_UCR_RX_ENABLED);
459
460        /* check to see if interrupts need to be enabled */
461        if ( info->iomode != TERMIOS_POLLED )
462        {
463                /* enable rx interrupts */
464                info->uimr |= MCF5282_UART_UIMR_FFULL;
465                MCF5282_UART_UIMR(minor) = info->uimr;
466        }
467
468        /* check to see if doing hardware flow control */
469        if ( info->hwflow )
470        {
471                /* assert the RTS line */
472                MCF5282_UART_UOP1(minor) = 1;
473        }
474
475        return( 0 );
476}
477
478
479
480/***************************************************************************
481   Function : IntUartInterruptClose
482
483   Description : This disables interrupts when the tty is closed.
484 ***************************************************************************/
485static int
486IntUartInterruptClose(int major, int minor, void *arg)
487{
488        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
489
490        /* disable the interrupts and the uart */
491        MCF5282_UART_UIMR(minor) = 0;
492        MCF5282_UART_UCR(minor) = (MCF5282_UART_UCR_TX_DISABLED | MCF5282_UART_UCR_RX_DISABLED);
493
494        /* reset values */
495        info->ttyp     = NULL;
496        info->uimr       = 0;
497        info->rx_in    = 0;
498        info->rx_out   = 0;
499
500        return( 0 );
501}
502
503/***************************************************************************
504   Function : IntUartTaskRead
505
506   Description : This reads all available characters from the internal uart
507   and places them into the termios buffer.  The rx interrupts will be
508   re-enabled after all data has been read.
509 ***************************************************************************/
510static int
511IntUartTaskRead(int minor)
512{
513        char                        buffer[RX_BUFFER_SIZE];
514        int                         count;
515        int                         rx_in;
516        int                         index = 0;
517        struct IntUartInfoStruct   *info  = &IntUartInfo[minor];
518
519        /* determine number of values to copy out */
520        rx_in = info->rx_in;
521        if ( info->rx_out <= rx_in )
522        {
523                count = rx_in - info->rx_out;
524        }
525        else
526        {
527                count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
528        }
529
530        /* copy data into local buffer from rx buffer */
531        while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) )
532        {
533                /* copy data byte */
534                buffer[index] = info->rx_buffer[info->rx_out];
535                index++;
536
537                /* increment rx buffer values */
538                info->rx_out++;
539                if ( info->rx_out >= RX_BUFFER_SIZE )
540                {
541                        info->rx_out = 0;
542                }
543        }
544
545        /* check to see if buffer is not empty */
546        if ( count > 0 )
547        {
548                /* set characters into termios buffer  */
549                rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
550        }
551
552        return( EOF );
553}
554
555
556
557/***************************************************************************
558   Function : IntUartPollRead
559
560   Description : This reads a character from the internal uart. It returns
561   to the caller without blocking if not character is waiting.
562 ***************************************************************************/
563static int
564IntUartPollRead (int minor)
565{
566        if ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_RXRDY) == 0 )
567                return(-1);
568
569        return(MCF5282_UART_URB(minor));
570}
571
572
573/***************************************************************************
574   Function : IntUartPollWrite
575
576   Description : This writes out each character in the buffer to the
577   appropriate internal uart channel waiting till each one is sucessfully
578   transmitted.
579 ***************************************************************************/
580static ssize_t
581IntUartPollWrite (int minor, const char *buf, size_t len)
582{
583        size_t retval = len;
584        /* loop over buffer */
585        while ( len-- )
586        {
587                /* block until we can transmit */
588                while ( (MCF5282_UART_USR(minor) & MCF5282_UART_USR_TXRDY) == 0 )
589                        continue;
590                /* transmit data byte */
591                MCF5282_UART_UTB(minor) = *buf++;
592        }
593        return retval;
594}
595
596/***************************************************************************
597   Function : console_initialize
598
599   Description : This initialises termios, all uart hardware before
600   registering /dev/tty devices for each channel and the system /dev/console.
601 ***************************************************************************/
602rtems_device_driver console_initialize(
603        rtems_device_major_number  major,
604        rtems_device_minor_number  minor,
605        void  *arg )
606{
607        rtems_status_code status;
608        int chan;
609
610        /* Set up TERMIOS */
611        rtems_termios_initialize ();
612
613        /* set io modes for the different channels and initialize device */
614        for ( chan = 0; chan < MAX_UART_INFO; chan++ )
615                IntUartInfo[chan].iomode = TERMIOS_IRQ_DRIVEN;
616        IntUartInitialize();
617
618        /* Register the console port */
619        status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT);
620        if ( status != RTEMS_SUCCESSFUL )
621        {
622                rtems_fatal_error_occurred (status);
623        }
624
625        /* Register the other ports */
626        if ( CONSOLE_PORT != 0 )
627        {
628                status = rtems_io_register_name ("/dev/tty00", major, 0);
629                if ( status != RTEMS_SUCCESSFUL )
630                {
631                        rtems_fatal_error_occurred (status);
632                }
633        }
634        if ( CONSOLE_PORT != 1 )
635        {
636                status = rtems_io_register_name ("/dev/tty01", major, 1);
637                if ( status != RTEMS_SUCCESSFUL )
638                {
639                        rtems_fatal_error_occurred (status);
640                }
641        }
642    status = rtems_io_register_name ("/dev/tty02", major, 2);
643    if ( status != RTEMS_SUCCESSFUL )
644    {
645        rtems_fatal_error_occurred (status);
646    }
647
648        return(RTEMS_SUCCESSFUL);
649}
650
651/***************************************************************************
652   Function : console_open
653
654   Description : This actually opens the device depending on the minor
655   number set during initialisation. The device specific access routines are
656   passed to termios when the devices is opened depending on whether it is
657   polled or not.
658 ***************************************************************************/
659rtems_device_driver console_open(
660        rtems_device_major_number major,
661        rtems_device_minor_number minor,
662        void  * arg)
663{
664        rtems_status_code                status = RTEMS_INVALID_NUMBER;
665        rtems_libio_open_close_args_t   *args   = (rtems_libio_open_close_args_t *)arg;
666        struct IntUartInfoStruct        *info;
667
668        static const rtems_termios_callbacks IntUartPollCallbacks = {
669                NULL,                             /* firstOpen */
670                NULL,                             /* lastClose */
671                IntUartPollRead,          /* pollRead */
672                IntUartPollWrite,         /* write */
673                IntUartSetAttributes, /* setAttributes */
674                NULL,                             /* stopRemoteTx */
675                NULL,                             /* startRemoteTx */
676                TERMIOS_POLLED            /* mode */
677        };
678        static const rtems_termios_callbacks IntUartIntrCallbacks = {
679                IntUartInterruptOpen,  /* firstOpen */
680                IntUartInterruptClose, /* lastClose */
681                NULL,                              /* pollRead */
682                IntUartInterruptWrite, /* write */
683                IntUartSetAttributes,  /* setAttributes */
684                NULL,                              /* stopRemoteTx */
685                NULL,                              /* startRemoteTx */
686                TERMIOS_IRQ_DRIVEN         /* mode */
687        };
688
689        static const rtems_termios_callbacks IntUartTaskCallbacks = {
690                IntUartInterruptOpen,  /* firstOpen */
691                IntUartInterruptClose, /* lastClose */
692                IntUartTaskRead,           /* pollRead */
693                IntUartInterruptWrite, /* write */
694                IntUartSetAttributes,  /* setAttributes */
695                NULL,                              /* stopRemoteTx */
696                NULL,                              /* startRemoteTx */
697                TERMIOS_TASK_DRIVEN        /* mode */
698        };
699
700        /* open the port depending on the minor device number */
701        if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) )
702        {
703                info = &IntUartInfo[minor];
704                switch ( info->iomode )
705                {
706                        case TERMIOS_POLLED:
707                                status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
708                                break;
709                        case TERMIOS_IRQ_DRIVEN:
710                                status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
711                                info->ttyp = args->iop->data1;
712                                break;
713                        case TERMIOS_TASK_DRIVEN:
714                                status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
715                                info->ttyp = args->iop->data1;
716                                break;
717                }
718        }
719
720        return( status );
721}
722
723/***************************************************************************
724   Function : console_close
725
726   Description : This closes the device via termios
727 ***************************************************************************/
728rtems_device_driver console_close(
729        rtems_device_major_number major,
730        rtems_device_minor_number minor,
731        void   * arg)
732{
733    return(rtems_termios_close (arg));
734}
735
736/******************
737*********************************************************
738   Function : console_read
739
740   Description : Read from the device via termios
741 ***************************************************************************/
742rtems_device_driver console_read(
743        rtems_device_major_number major,
744        rtems_device_minor_number minor,
745        void  * arg)
746{
747    return(rtems_termios_read (arg));
748}
749
750/***************************************************************************
751   Function : console_write
752
753   Description : Write to the device via termios
754 ***************************************************************************/
755rtems_device_driver console_write(
756        rtems_device_major_number major,
757        rtems_device_minor_number minor,
758        void  * arg)
759{
760    return(rtems_termios_write (arg));
761}
762
763/***************************************************************************
764   Function : console_ioctl
765
766   Description : Pass the IOCtl call to termios
767 ***************************************************************************/
768rtems_device_driver console_control(
769        rtems_device_major_number major,
770        rtems_device_minor_number minor,
771        void  * arg)
772{
773    return( rtems_termios_ioctl (arg) );
774}
775
Note: See TracBrowser for help on using the repository browser.