source: rtems/c/src/lib/libbsp/m68k/genmcf548x/console/console.c @ 00e8c344

5
Last change on this file since 00e8c344 was 21bab83, checked in by Joel Sherrill <joel@…>, on 03/29/16 at 18:10:51

m68k/genmcf548x: Remove include of <rtems/console.h> from <bsp.h> and fix warnings

  • Property mode set to 100644
File size: 24.7 KB
Line 
1/*===============================================================*\
2| Project: RTEMS generic mcf548x BSP                              |
3+-----------------------------------------------------------------+
4| File: console.c                                                 |
5+-----------------------------------------------------------------+
6| The file contains the console driver code of generic MCF548x    |
7| BSP.                                                            |
8+-----------------------------------------------------------------+
9|                    Copyright (c) 2007                           |
10|                    Embedded Brains GmbH                         |
11|                    Obere Lagerstr. 30                           |
12|                    D-82178 Puchheim                             |
13|                    Germany                                      |
14|                    rtems@embedded-brains.de                     |
15+-----------------------------------------------------------------+
16|                                                                 |
17| Parts of the code has been derived from the "dBUG source code"  |
18| package Freescale is providing for M548X EVBs. The usage of     |
19| the modified or unmodified code and it's integration into the   |
20| generic mcf548x BSP has been done according to the Freescale    |
21| license terms.                                                  |
22|                                                                 |
23| The Freescale license terms can be reviewed in the file         |
24|                                                                 |
25|    Freescale_license.txt                                        |
26|                                                                 |
27+-----------------------------------------------------------------+
28|                                                                 |
29| The generic mcf548x BSP has been developed on the basic         |
30| structures and modules of the av5282 BSP.                       |
31|                                                                 |
32+-----------------------------------------------------------------+
33|                                                                 |
34| The license and distribution terms for this file may be         |
35| found in the file LICENSE in this distribution or at            |
36|                                                                 |
37| http://www.rtems.org/license/LICENSE.                           |
38|                                                                 |
39+-----------------------------------------------------------------+
40|                                                                 |
41|   date                      history                        ID   |
42| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
43| 12.11.07                    1.0                            ras  |
44|                                                                 |
45\*===============================================================*/
46
47 /*
48  *  Multi UART console serial I/O.
49  *
50  * TO DO: Add DMA input/output
51  */
52
53#include <stdio.h>
54#include <fcntl.h>
55#include <termios.h>
56#include <malloc.h>
57#include <rtems/mw_uid.h>
58
59#include <bsp.h>
60#include <bsp/irq-generic.h>
61#include <rtems/libio.h>
62#include <rtems/termiostypes.h>
63#include <rtems/console.h>
64#include <rtems/bspIo.h>
65
66#define UART_INTC0_IRQ_VECTOR(x) (64+35-(x))
67
68#define MCF548X_PSC_SR_ERROR ( MCF548X_PSC_SR_RB_NEOF   | \
69                           MCF548X_PSC_SR_FE_PHYERR | \
70                           MCF548X_PSC_SR_PE_CRCERR | \
71                           MCF548X_PSC_SR_OE )
72
73static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len);
74static int IntUartPollRead (int minor);
75
76static void
77_BSP_null_char( char c )
78{
79        int level;
80
81    if (c == '\n')
82        _BSP_null_char('\r');
83        rtems_interrupt_disable(level);
84    while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY)))
85        continue;
86    *((uint8_t *) &MCF548X_PSC_TB(CONSOLE_PORT)) = c;
87    while (!((MCF548X_PSC_SR(CONSOLE_PORT) & MCF548X_PSC_SR_TXRDY)))
88        continue;
89        rtems_interrupt_enable(level);
90}
91BSP_output_char_function_type     BSP_output_char = _BSP_null_char;
92BSP_polling_getchar_function_type BSP_poll_char = NULL;
93
94#define MAX_UART_INFO     4
95#define RX_BUFFER_SIZE    248
96
97struct IntUartInfoStruct
98{
99        int                    iomode;
100        volatile int           imr;
101        int                    baud;
102        int                    databits;
103        int                    parity;
104        int                    stopbits;
105        int                    hwflow;
106        int                    rx_in;
107        int                    rx_out;
108        char                   rx_buffer[RX_BUFFER_SIZE];
109        void                  *ttyp;
110};
111
112struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO];
113
114static int GetBaud( int baudHandle )
115{
116        int baud = BSP_CONSOLE_BAUD;
117        switch(baudHandle)
118        {
119                case B0:
120                        baud = (int)0;
121                        break;
122                case B1200:
123                        baud = (int)1200;
124                        break;
125                case B2400:
126                        baud = (int)2400;
127                        break;
128                case B4800:
129                        baud = (int)4800;
130                        break;
131                case B9600:
132                        baud = (int)9600;
133                        break;
134                case B19200:
135                        baud = (int)19200;
136                        break;
137                case B38400:
138                        baud = (int)38400;
139                        break;
140                case B57600:
141                        baud = (int)57600;
142                        break;
143                case B115200:
144                        baud = (int)115200;
145                        break;
146        }
147        return baud;
148}
149
150/***************************************************************************
151   Function : IntUartSet
152
153   Description : This updates the hardware UART settings.
154 ***************************************************************************/
155static void
156IntUartSet(int minor, int baud, int databits, int parity, int stopbits, int hwflow)
157{
158        uint8_t                    psc_mode_1 = 0, psc_mode_2 = 0;
159        uint16_t                   divider;
160        int                        level;
161        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
162
163        rtems_interrupt_disable(level);
164
165        /* disable interrupts, clear RTS line, and disable the UARTS */
166        /* Mask all psc interrupts */
167        MCF548X_PSC_IMR(minor) = 0x0000;
168
169        /* Clear RTS to send */
170        MCF548X_PSC_OPSET(minor) &= ~(MCF548X_PSC_OPSET_RTS);
171
172        /* Disable receiver and transmitter */
173    MCF548X_PSC_CR(minor) &= ~(MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED);
174
175    /* provide gpio settings */
176    switch (minor)
177          {
178      case 0:
179        MCF548X_GPIO_PAR_PSC0    = (0 | MCF548X_GPIO_PAR_PSC0_PAR_TXD0 | MCF548X_GPIO_PAR_PSC0_PAR_RXD0);
180
181        if(hwflow)
182          {
183          MCF548X_GPIO_PAR_PSC0 |= (0 | MCF548X_GPIO_PAR_PSC0_PAR_CTS0_CTS | MCF548X_GPIO_PAR_PSC0_PAR_RTS0_RTS);
184          }
185        break;
186      case 1:
187        MCF548X_GPIO_PAR_PSC1    = (0 | MCF548X_GPIO_PAR_PSC1_PAR_TXD1 | MCF548X_GPIO_PAR_PSC1_PAR_RXD1);
188
189        if(hwflow)
190          {
191          MCF548X_GPIO_PAR_PSC1 |= (0 | MCF548X_GPIO_PAR_PSC1_PAR_CTS1_CTS | MCF548X_GPIO_PAR_PSC1_PAR_RTS1_RTS);
192          }
193        break;
194      case 2:
195        MCF548X_GPIO_PAR_PSC2    = (0 | MCF548X_GPIO_PAR_PSC2_PAR_TXD2 | MCF548X_GPIO_PAR_PSC2_PAR_RXD2);
196
197        if(hwflow)
198          {
199          MCF548X_GPIO_PAR_PSC2 |= (0 | MCF548X_GPIO_PAR_PSC2_PAR_CTS2_CTS | MCF548X_GPIO_PAR_PSC2_PAR_RTS2_RTS);
200          }
201        break;
202      case 3:
203        MCF548X_GPIO_PAR_PSC3    = (0 | MCF548X_GPIO_PAR_PSC3_PAR_TXD3 | MCF548X_GPIO_PAR_PSC3_PAR_RXD3);
204
205        if(hwflow)
206          {
207          MCF548X_GPIO_PAR_PSC3 |= (0 | MCF548X_GPIO_PAR_PSC3_PAR_CTS3_CTS | MCF548X_GPIO_PAR_PSC3_PAR_RTS3_RTS);
208          }
209        break;
210      default:
211        break;
212        }
213
214    /* save the current values */
215        info->imr      = 0;
216        info->baud     = baud;
217        info->databits = databits;
218        info->parity   = parity;
219        info->stopbits = stopbits;
220        info->hwflow   = hwflow;
221
222    /* Put PSC in UART mode */
223        MCF548X_PSC_SICR(minor) = MCF548X_PSC_SICR_SIM_UART;
224
225    /* set the baud rate values */
226        MCF548X_PSC_CSR(minor) = (0 | MCF548X_PSC_CSR_RCSEL_SYS_CLK | MCF548X_PSC_CSR_TCSEL_SYS_CLK);
227
228        /* Calculate baud settings */
229        divider = (uint16_t)((get_CPU_clock_speed())/(baud * 32));
230        MCF548X_PSC_CTUR(minor) =  (uint8_t) ((divider >> 8) & 0xFF);
231        MCF548X_PSC_CTLR(minor) =  (uint8_t) (divider & 0xFF);
232
233        /* Reset transmitter, receiver, mode register, and error conditions */
234        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_RX;
235        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_TX;
236        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_ERROR;
237        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_BKCHGINT;
238        MCF548X_PSC_CR(minor) = MCF548X_PSC_CR_RESET_MR;
239
240        /* check to see if doing hardware flow control */
241        if ( hwflow )
242        {
243                /* set hardware flow options */
244                psc_mode_1 = MCF548X_PSC_MR_RXRTS;
245        psc_mode_2 = MCF548X_PSC_MR_TXCTS;
246        }
247
248    /* set mode registers */
249        psc_mode_1 |= (uint8_t)(parity | databits);
250    psc_mode_2 |= (uint8_t)(stopbits);
251
252    /* set mode registers */
253        MCF548X_PSC_MR(minor) = psc_mode_1;
254    MCF548X_PSC_MR(minor) = psc_mode_2;
255
256    /* Setup FIFO Alarms */
257    MCF548X_PSC_RFAR(minor) = MCF548X_PSC_RFAR_ALARM(248);
258        MCF548X_PSC_TFAR(minor) = MCF548X_PSC_TFAR_ALARM(248);
259
260        /* check to see if interrupts need to be enabled */
261        if ( info->iomode != TERMIOS_POLLED )
262        {
263                /* enable rx interrupts */
264                info->imr |= MCF548X_PSC_IMR_RXRDY_FU;
265                MCF548X_PSC_IMR(minor) = info->imr;
266        }
267
268        /* check to see if doing hardware flow control */
269        if ( hwflow )
270        {
271                /* assert the RTS line */
272                MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS;
273        }
274
275        rtems_interrupt_enable(level);
276
277    /* Enable receiver and transmitter */
278        MCF548X_PSC_CR(minor) =(0 | MCF548X_PSC_CR_RX_ENABLED | MCF548X_PSC_CR_TX_ENABLED);
279
280
281}
282
283/***************************************************************************
284   Function : IntUartSetAttributes
285
286   Description : This provides the hardware-dependent portion of tcsetattr().
287   value and sets it. At the moment this just sets the baud rate.
288
289   Note: The highest baudrate is 115200 as this stays within
290   an error of +/- 5% at 25MHz processor clock
291 ***************************************************************************/
292static int
293IntUartSetAttributes(int minor, const struct termios *t)
294{
295/* set default index values */
296#ifdef HAS_DBUG
297        int                         baud     = DBUG_SETTINGS.console_baudrate;
298#else
299        int                         baud     = (int)BSP_CONSOLE_BAUD;
300#endif
301        int                         databits = (int)MCF548X_PSC_MR_BC_8;
302        int                         parity   = (int)MCF548X_PSC_MR_PM_NONE;
303        int                         stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_1;
304        int                         hwflow   = (int)1;
305        struct IntUartInfoStruct   *info     = &IntUartInfo[minor];
306
307        /* check to see if input is valid */
308        if ( t != (const struct termios *)0 )
309        {
310                /* determine baud rate index */
311                baud = GetBaud( t->c_cflag & CBAUD );
312
313                /* determine data bits */
314                switch ( t->c_cflag & CSIZE )
315                {
316                        case CS5:
317                                databits = (int)MCF548X_PSC_MR_BC_5;
318                                break;
319                        case CS6:
320                                databits = (int)MCF548X_PSC_MR_BC_6;
321                                break;
322                        case CS7:
323                                databits = (int)MCF548X_PSC_MR_BC_7;
324                                break;
325                        case CS8:
326                                databits = (int)MCF548X_PSC_MR_BC_8;
327                                break;
328                }
329
330                /* determine if parity is enabled */
331                if ( t->c_cflag & PARENB )
332                {
333                        if ( t->c_cflag & PARODD )
334                        {
335                                /* odd parity */
336                                parity = (int)MCF548X_PSC_MR_PM_ODD;
337                        }
338                        else
339                        {
340                                /* even parity */
341                                parity = (int)MCF548X_PSC_MR_PM_EVEN;
342                        }
343                }
344
345                /* determine stop bits */
346                if ( t->c_cflag & CSTOPB )
347                {
348                        /* two stop bits */
349                        stopbits = (int)MCF548X_PSC_MR_SB_STOP_BITS_2;
350                }
351
352                /* check to see if hardware flow control */
353                if ( t->c_cflag & CRTSCTS )
354                {
355                        hwflow = 1;
356                }
357        }
358
359        /* check to see if values have changed */
360        if ( ( baud     != info->baud     ) ||
361                 ( databits != info->databits ) ||
362                 ( parity   != info->parity   ) ||
363                 ( stopbits != info->stopbits ) ||
364                 ( hwflow   != info->hwflow   ) )
365        {
366
367                /* call function to set values */
368                IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
369        }
370
371return RTEMS_SUCCESSFUL;
372
373}
374
375/***************************************************************************
376   Function : IntUartInterruptHandler
377
378   Description : This is the interrupt handler for the internal uart. It
379   determines which channel caused the interrupt before queueing any received
380   chars and dequeueing chars waiting for transmission.
381 ***************************************************************************/
382static rtems_isr
383IntUartInterruptHandler(rtems_vector_number v)
384{
385        unsigned int                chan = v - UART_INTC0_IRQ_VECTOR(0);
386        struct IntUartInfoStruct   *info = &IntUartInfo[chan];
387
388        /* check to see if received data */
389        if ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_RXRDY_FU )
390        {
391                /* read data and put into the receive buffer */
392                while ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_RXRDY )
393                {
394
395                   /* put data in rx buffer */
396                        info->rx_buffer[info->rx_in] = *((volatile uint8_t *)&MCF548X_PSC_RB(chan));
397
398           /* check for errors */
399           if ( MCF548X_PSC_SR(chan) & MCF548X_PSC_SR_ERROR )
400                        {
401                                /* clear the error */
402                                MCF548X_PSC_CR(chan) = MCF548X_PSC_CR_RESET_ERROR;
403                        }
404
405                        /* update buffer values */
406                        info->rx_in++;
407
408                        if ( info->rx_in >= RX_BUFFER_SIZE )
409                        {
410                                info->rx_in = 0;
411                        }
412                }
413                /* Make sure the port has been opened */
414                if ( info->ttyp )
415                {
416
417                        /* check to see if task driven */
418                        if ( info->iomode == TERMIOS_TASK_DRIVEN )
419                        {
420                                /* notify rx task that rx buffer has data */
421                                rtems_termios_rxirq_occured(info->ttyp);
422                        }
423                        else
424                        {
425                                /* Push up the received data */
426                                rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer, info->rx_in);
427                                info->rx_in    = 0;
428                        }
429                }
430        }
431
432        /* check to see if data needs to be transmitted */
433        if ( ( info->imr & MCF548X_PSC_IMR_TXRDY ) &&
434                 ( MCF548X_PSC_ISR(chan) & MCF548X_PSC_ISR_TXRDY ) )
435        {
436
437                /* disable tx interrupts */
438                info->imr &= ~MCF548X_PSC_IMR_TXRDY;
439                MCF548X_PSC_IMR(chan) = info->imr;
440
441                /* tell upper level that character has been sent */
442                if ( info->ttyp )
443                        rtems_termios_dequeue_characters(info->ttyp, 1);
444        }
445
446}
447
448/***************************************************************************
449   Function : IntUartInitialize
450
451   Description : This initialises the internal uart hardware for all
452   internal uarts. If the internal uart is to be interrupt driven then the
453   interrupt vectors are hooked.
454 ***************************************************************************/
455static void
456IntUartInitialize(void)
457{
458    unsigned int        chan;
459        struct IntUartInfoStruct   *info;
460        rtems_isr_entry old_handler;
461
462        for ( chan = 0; chan < MAX_UART_INFO; chan++ )
463        {
464                info = &IntUartInfo[chan];
465
466                info->ttyp     = NULL;
467                info->rx_in    = 0;
468                info->rx_out   = 0;
469                info->baud     = -1;
470                info->databits = -1;
471                info->parity   = -1;
472                info->stopbits = -1;
473                info->hwflow   = -1;
474
475                MCF548X_PSC_ACR(chan) = 0;
476                MCF548X_PSC_IMR(chan) = 0;
477                if ( info->iomode != TERMIOS_POLLED )
478                {
479                        rtems_interrupt_catch (IntUartInterruptHandler,
480                                                                   UART_INTC0_IRQ_VECTOR(chan),
481                                                                   &old_handler);
482                }
483
484                /* set uart default values */
485                IntUartSetAttributes(chan, NULL);
486
487                /* unmask interrupt */
488                bsp_interrupt_vector_enable(MCF548X_IRQ_PSC(chan));
489        } /* of chan loop */
490
491
492} /* IntUartInitialise */
493
494/***************************************************************************
495   Function : IntUartInterruptWrite
496
497   Description : This writes a single character to the appropriate uart
498   channel. This is either called during an interrupt or in the user's task
499   to initiate a transmit sequence. Calling this routine enables Tx
500   interrupts.
501 ***************************************************************************/
502static ssize_t
503IntUartInterruptWrite (int minor, const char *buf, size_t len)
504{
505        if (len > 0) {
506                /* write out character */
507                *(volatile uint8_t *)(&MCF548X_PSC_TB(minor)) = *buf;
508
509                /* enable tx interrupt */
510                IntUartInfo[minor].imr |= MCF548X_PSC_IMR_TXRDY;
511                MCF548X_PSC_IMR(minor) = IntUartInfo[minor].imr;
512        }
513
514        return 0;
515}
516
517/***************************************************************************
518   Function : IntUartInterruptOpen
519
520   Description : This enables interrupts when the tty is opened.
521 ***************************************************************************/
522static int
523IntUartInterruptOpen(int major, int minor, void *arg)
524{
525        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
526
527        /* enable the uart */
528        MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED);
529
530        /* check to see if interrupts need to be enabled */
531        if ( info->iomode != TERMIOS_POLLED )
532        {
533                /* enable rx interrupts */
534                info->imr |= MCF548X_PSC_IMR_RXRDY_FU;
535                MCF548X_PSC_IMR(minor) = info->imr;
536        }
537
538        /* check to see if doing hardware flow control */
539        if ( info->hwflow )
540        {
541                /* assert the RTS line */
542                MCF548X_PSC_OPSET(minor) = MCF548X_PSC_OPSET_RTS;
543        }
544
545        return 0;
546}
547
548
549/***************************************************************************
550   Function : IntUartInterruptClose
551
552   Description : This disables interrupts when the tty is closed.
553 ***************************************************************************/
554static int
555IntUartInterruptClose(int major, int minor, void *arg)
556{
557        struct IntUartInfoStruct   *info = &IntUartInfo[minor];
558
559        /* disable the interrupts and the uart */
560        MCF548X_PSC_IMR(minor) = 0;
561        MCF548X_PSC_CR(minor) = (MCF548X_PSC_CR_TX_ENABLED | MCF548X_PSC_CR_RX_ENABLED);
562
563        /* reset values */
564        info->ttyp     = NULL;
565        info->imr       = 0;
566        info->rx_in    = 0;
567        info->rx_out   = 0;
568
569        return 0;
570}
571
572/***************************************************************************
573   Function : IntUartTaskRead
574
575   Description : This reads all available characters from the internal uart
576   and places them into the termios buffer.  The rx interrupts will be
577   re-enabled after all data has been read.
578 ***************************************************************************/
579static int
580IntUartTaskRead(int minor)
581{
582        char                        buffer[RX_BUFFER_SIZE];
583        int                         count;
584        int                         rx_in;
585        int                         index = 0;
586        struct IntUartInfoStruct   *info  = &IntUartInfo[minor];
587
588        /* determine number of values to copy out */
589        rx_in = info->rx_in;
590        if ( info->rx_out <= rx_in )
591        {
592                count = rx_in - info->rx_out;
593        }
594        else
595        {
596                count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
597        }
598
599        /* copy data into local buffer from rx buffer */
600        while ( ( index < count ) && ( index < RX_BUFFER_SIZE ) )
601        {
602                /* copy data byte */
603                buffer[index] = info->rx_buffer[info->rx_out];
604                index++;
605
606                /* increment rx buffer values */
607                info->rx_out++;
608                if ( info->rx_out >= RX_BUFFER_SIZE )
609                {
610                        info->rx_out = 0;
611                }
612        }
613
614        /* check to see if buffer is not empty */
615        if ( count > 0 )
616        {
617                /* set characters into termios buffer  */
618                rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
619        }
620
621        return EOF;
622}
623
624
625/***************************************************************************
626   Function : IntUartPollRead
627
628   Description : This reads a character from the internal uart. It returns
629   to the caller without blocking if not character is waiting.
630 ***************************************************************************/
631static int
632IntUartPollRead (int minor)
633{
634if (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_RXRDY)))
635                return(-1);
636
637        return *((uint8_t *)&MCF548X_PSC_RB(minor));
638}
639
640
641/***************************************************************************
642   Function : IntUartPollWrite
643
644   Description : This writes out each character in the buffer to the
645   appropriate internal uart channel waiting till each one is sucessfully
646   transmitted.
647 ***************************************************************************/
648static ssize_t
649IntUartPollWrite (int minor, const char *buf, size_t len)
650{
651        size_t retval = len;
652/* loop over buffer */
653        while ( len-- )
654        {
655                /* block until we can transmit */
656                while (!((MCF548X_PSC_SR(minor) & MCF548X_PSC_SR_TXRDY)))
657                        continue;
658                /* transmit data byte */
659                *((uint8_t *)&MCF548X_PSC_TB(minor)) = *buf++;
660        }
661        return retval;
662}
663
664/***************************************************************************
665   Function : console_initialize
666
667   Description : This initialises termios, both sets of uart hardware before
668   registering /dev/tty devices for each channel and the system /dev/console.
669 ***************************************************************************/
670rtems_device_driver console_initialize(
671        rtems_device_major_number  major,
672        rtems_device_minor_number  minor,
673        void  *arg )
674{
675        rtems_status_code status;
676
677
678        /* Set up TERMIOS */
679        rtems_termios_initialize ();
680
681        /* set io modes for the different channels and initialize device */
682    IntUartInfo[minor].iomode = TERMIOS_IRQ_DRIVEN; //TERMIOS_POLLED;
683        IntUartInitialize();
684
685        /* Register the console port */
686        status = rtems_io_register_name ("/dev/console", major, CONSOLE_PORT);
687        if ( status != RTEMS_SUCCESSFUL )
688        {
689                rtems_fatal_error_occurred (status);
690        }
691
692        /* Register the other port */
693        if ( CONSOLE_PORT != 0 )
694        {
695                status = rtems_io_register_name ("/dev/tty00", major, 0);
696                if ( status != RTEMS_SUCCESSFUL )
697                {
698                        rtems_fatal_error_occurred (status);
699                }
700        }
701        if ( CONSOLE_PORT != 1 )
702        {
703                status = rtems_io_register_name ("/dev/tty01", major, 1);
704                if ( status != RTEMS_SUCCESSFUL )
705                {
706                        rtems_fatal_error_occurred (status);
707                }
708        }
709
710        return(RTEMS_SUCCESSFUL);
711}
712
713/***************************************************************************
714   Function : console_open
715
716   Description : This actually opens the device depending on the minor
717   number set during initialisation. The device specific access routines are
718   passed to termios when the devices is opened depending on whether it is
719   polled or not.
720 ***************************************************************************/
721rtems_device_driver console_open(
722        rtems_device_major_number major,
723        rtems_device_minor_number minor,
724        void  * arg)
725{
726    rtems_status_code                status = RTEMS_INVALID_NUMBER;
727        rtems_libio_open_close_args_t   *args   = (rtems_libio_open_close_args_t *)arg;
728        struct IntUartInfoStruct        *info;
729
730        static const rtems_termios_callbacks IntUartPollCallbacks = {
731                NULL,                             /* firstOpen */
732                NULL,                             /* lastClose */
733                IntUartPollRead,          /* pollRead */
734                IntUartPollWrite,         /* write */
735                IntUartSetAttributes, /* setAttributes */
736                NULL,                             /* stopRemoteTx */
737                NULL,                             /* startRemoteTx */
738                TERMIOS_POLLED            /* mode */
739        };
740        static const rtems_termios_callbacks IntUartIntrCallbacks = {
741                IntUartInterruptOpen,  /* firstOpen */
742                IntUartInterruptClose, /* lastClose */
743                NULL,                              /* pollRead */
744                IntUartInterruptWrite, /* write */
745                IntUartSetAttributes,  /* setAttributes */
746                NULL,                              /* stopRemoteTx */
747                NULL,                              /* startRemoteTx */
748                TERMIOS_IRQ_DRIVEN         /* mode */
749        };
750
751        static const rtems_termios_callbacks IntUartTaskCallbacks = {
752                IntUartInterruptOpen,  /* firstOpen */
753                IntUartInterruptClose, /* lastClose */
754                IntUartTaskRead,           /* pollRead */
755                IntUartInterruptWrite, /* write */
756                IntUartSetAttributes,  /* setAttributes */
757                NULL,                              /* stopRemoteTx */
758                NULL,                              /* startRemoteTx */
759                TERMIOS_TASK_DRIVEN        /* mode */
760        };
761
762        /* open the port depending on the minor device number */
763        if ( ( minor >= 0 ) && ( minor < MAX_UART_INFO ) )
764        {
765                info = &IntUartInfo[minor];
766                switch ( info->iomode )
767                {
768                        case TERMIOS_POLLED:
769                                status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
770                                break;
771                        case TERMIOS_IRQ_DRIVEN:
772                                status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
773                                info->ttyp = args->iop->data1;
774                                break;
775                        case TERMIOS_TASK_DRIVEN:
776                                status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
777                                info->ttyp = args->iop->data1;
778                                break;
779                }
780        }
781
782        return( status );
783}
784
785/***************************************************************************
786   Function : console_close
787
788   Description : This closes the device via termios
789 ***************************************************************************/
790rtems_device_driver console_close(
791        rtems_device_major_number major,
792        rtems_device_minor_number minor,
793        void   * arg)
794{
795    return(rtems_termios_close (arg));
796}
797
798/***************************************************************************
799   Function : console_read
800
801   Description : Read from the device via termios
802 ***************************************************************************/
803rtems_device_driver console_read(
804        rtems_device_major_number major,
805        rtems_device_minor_number minor,
806        void  * arg)
807{
808    return(rtems_termios_read (arg));
809}
810
811/***************************************************************************
812   Function : console_write
813
814   Description : Write to the device via termios
815 ***************************************************************************/
816rtems_device_driver console_write(
817        rtems_device_major_number major,
818        rtems_device_minor_number minor,
819        void  * arg)
820{
821    return(rtems_termios_write (arg));
822}
823
824/***************************************************************************
825   Function : console_ioctl
826
827   Description : Pass the IOCtl call to termios
828 ***************************************************************************/
829rtems_device_driver console_control(
830        rtems_device_major_number major,
831        rtems_device_minor_number minor,
832        void  * arg)
833{
834    return( rtems_termios_ioctl (arg) );
835}
Note: See TracBrowser for help on using the repository browser.