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

Last change on this file since c08799e was c08799e, checked in by Joel Sherrill <joel@…>, on Mar 29, 2016 at 7:05:33 PM

m68k/genmcf548x/console/console.c: Remove unneeded include of <rtems/mw_uid.h>

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